2011-01-31 2 views
0

Я пытаюсь наблюдать свойство BOOL вида. Поскольку существуют различные виды наблюдения, я проверяю селектор и использую функцию Performlect, чтобы получить значение.Неожиданный EXC_BAD с NSNumber

if([tab respondsToSelector:@selector(canGoBack)]) { 
    [tab addObserver:self forKeyPath:@"canGoBack" 
    options:NSKeyValueObservingOptionNew 
    context:NULL]; 
    NSNumber* value = (NSNumber*)[tab performSelector:@selector(canGoBack)]; 
    canGoBack = [value boolValue]; 
} 

Однако, я случайно получил EXC_BAD в «[value boolValue]». Я проверил вкладку, она существовала, когда произошла ошибка.

После того как я изменил код на следующее, ошибка никогда не была поймана снова.

if([tab respondsToSelector:@selector(canGoBack)]) { 
    [tab addObserver:self forKeyPath:@"canGoBack" 
     options:NSKeyValueObservingOptionNew 
     context:NULL]; 
     canGoBack = [tab canGoBack]; 
// NSNumber* value = (NSNumber*)[tab performSelector:@selector(canGoBack)]; 
// canGoBack = [value boolValue]; 
    } 

Интересно, почему?

ответ

0

Я думаю, что вы используете canGoBack как функция а также как bool значение. Это проблема.

0

потому что ваш метод canGoBack возвращает BOOL, а performSelector: ожидает возвращаемое значение типа id. результат BOOL не будет адресом действительного объекта objc, который вы его передали, а затем используйте для отправки сообщения objc.

+0

Если это случайный адрес, почему значение всегда правы, когда нет EXC_BAD? Есть ли механизм автоматического литья? – Slavik

+0

@Slavik адрес может быть предсказуемым, но бесполезен и определенно будет вызывать неопределенное поведение, если вы попытаетесь использовать подписанный результат char как объект objc. в этом случае автоматическое преобразование не выполняется, потому что нельзя использовать символ char как объект objc. вы можете создать свою собственную функцию, которая использует NSInvocation (или интерфейсы в 'obc /'), если вы хотите добиться чего-то функционально сопоставимого. – justin

+0

Спасибо. BTW, есть ли комментарий для поведения performSelector, когда возвращаемое значение не является NSObject. – Slavik

0

canGoBack - это метод выбора, и вы пытаетесь присвоить значение bool этому методу? как можно это сделать? .. и, во-вторых, думаете, вы уверены, что NSNumber, который вы получаете, всего 1 или 0, иначе typecasting NSNumber для bool не используется полностью

+0

canGoBack объявлен как свойство. objc будет генерировать метод get для свойства. По этой причине он может ответить на @selector (canGoBack). Я пытаюсь получить значение bool из этого метода? Тем не менее, я нашел, что он может быть успешным большую часть времени. Тогда почему это терпит неудачу? – Slavik

+0

u уже упомянутый canGoBack - метод. Вы не можете присвоить значение методу – Raj

Смежные вопросы