Не получается правильный вывод в Xcode, Objective-C

Я читаю эту книгу по программированию со следующим кодом

#import "Fraction.h"
int main (int argc, char * argv [])
{
    @autoreleasepool {
        Fraction *f = [[Fraction alloc] init];
        [f noSuchMethod];
        NSLog (@"Execution continues!");
    }
    return 0;
}

По-видимому, он должен дать мне следующий вывод:

* Завершение работы приложения из-за необработанного исключения "NSInvalidArgumentException", причина: "-[фракция noSuchMethod]: нераспознанный селектор отправлен экземпляру 0x103f00" * Стек вызовов при первом броске:")

Вместо этого я просто получаю сообщение об ошибке: «Нет видимого @interface для «Дроби» объявляет селектор «noSuchMethod»

Это потому, что у меня более новая версия xcode, или я что-то не так делаю? Мне это кажется довольно прямолинейным.

Изменить:

Также... Будет ли этот следующий код работать в новейшей версии xcode?

int main (int argc, char * argv [])
{
    @autoreleasepool {
        Fraction *f = [[Fraction alloc] init];
        @try {
            [f noSuchMethod];
        }
        @catch (NSException *exception) {
            NSLog(@"Caught %@%@", [exception name], [exception reason]);
        }
        NSLog (@"Execution continues!");
    }
return 0;
}

Изменить № 2: введите здесь описание изображения


person RCYup    schedule 07.12.2012    source источник
comment
возможный дубликат Почему "неизвестно метод для селектора x' серьезная ошибка в ARC?   -  person trojanfoe    schedule 07.12.2012


Ответы (1)


Xcode не позволяет компилировать, если вы вызываете метод, которого точно не существует.

В противном случае используйте метод performSelector:.

ИЗМЕНИТЬ

Если вы напрямую вызываете метод, он не будет компилироваться, как в первоначальном вопросе, который вы задали.

Если вы все еще хотите вызвать этот метод по какой-то причине, потому что, может быть, он частный или что-то еще, вы можете вызвать его через PerformSelector:.

Он по-прежнему скажет вам, что объект может не реагировать на него. Вы можете подавить предупреждение, как вы можете видеть здесь:

http://www.stackoverflow.com/a/7933931/1320374

person IluTov    schedule 07.12.2012
comment
Книга, вероятно, относится к более ранней версии Xcode. Версия, использованная в книге, по-видимому, не проверяла существование метода во время компиляции и поэтому вызывала исключение во время выполнения. Версия Xcode, которую вы сейчас используете, проверяет существование рассматриваемого метода во время компиляции. - person FluffulousChimp; 07.12.2012
comment
Спасибо за ваш быстрый ответ. Не могли бы вы дать мне больше информации о моем последнем редактировании вопроса? Спасибо! - person RCYup; 07.12.2012
comment
Не дает компилировать? Он просто генерирует предупреждение, но, безусловно, компилируется. - person trojanfoe; 07.12.2012
comment
@RCYup Не из-за отсутствующего метода, а из-за отсутствующего класса! - person trojanfoe; 07.12.2012
comment
@trojanfoe Я определил класс. Это дает мне ошибку. Даже если я изменю его на id, он все равно выдает ту же ошибку. - person RCYup; 07.12.2012
comment
@RCYup Я не вижу класса, определенного в опубликованном вами коде. РЕДАКТИРОВАТЬ: это, очевидно, в Fraction.h doh. Однако я этого не понимаю. Я сталкивался с этим много раз в своем собственном коде, и компилятор генерирует предупреждение, что класс X может не реагировать на селектор Y, но он все равно его компилирует. - person trojanfoe; 07.12.2012
comment
@trojanfoe Я не включил #import Fraction.h в свой пример, но он есть в моем коде. - person RCYup; 07.12.2012
comment
Нет, как я написал в своем ответе. Вы можете вызвать PerformSelector: для объекта Fraction. Затем он скомпилируется, и вы получите исключение - person IluTov; 07.12.2012
comment
Итак, в чем разница между классом предупреждения может не реагировать на селектор и ошибкой, в которой нет известного метода экземпляра для селектора? Определен ли селектор в другом классе, поэтому компилятор знает, что есть селектор с таким именем (которого в данном случае нет)? - person trojanfoe; 07.12.2012
comment
@trojanfoe Если вы напрямую вызываете метод, он не будет компилироваться, как в первоначальном вопросе, который вы задали, хотя, если вы все еще хотите вызвать этот метод по какой-то причине, потому что, возможно, он частный или что-то еще, вы можете вызвать его через performSelector: . Он по-прежнему скажет вам, что объект может не реагировать на него. Вы можете отключить предупреждение, как показано здесь: stackoverflow.com/a/7933931/1320374 - person IluTov; 07.12.2012
comment
@RCYup Компилятор прерывает компиляцию, как только получает какие-либо ошибки, это то, что мы называем отказом от компиляции. - person IluTov; 07.12.2012
comment
О, это происходит только при использовании ARC? Это объяснило бы многое! - person trojanfoe; 07.12.2012
comment
@trojanfoe Почему АРК? Это не имеет ничего общего с ARC - person IluTov; 07.12.2012
comment
@NSAddict Вы уверены? Как я уже упоминал, в моем коде (MRR) подобные ошибки вызывают только предупреждение в Xcode. - person trojanfoe; 07.12.2012
comment
@trojanfoe ARC просто вставляет вызовы retain и release за вас. Когда вы только получаете предупреждение? - person IluTov; 07.12.2012
comment
@NSAddict Ну, я не уверен (мне нужно было бы создать 2 примера проектов, чтобы знать наверняка, и меня нет рядом с моим Mac), однако вопрос SO, на который вы ссылались, имел принятый ответ с моим предположением об этом: так как selector неизвестен компилятору, ARC не может обеспечить надлежащее управление памятью, что заставило меня подумать, что это разница в поведении. - person trojanfoe; 07.12.2012
comment
@trojanfoe На самом деле речь идет о LLVM 3.0 compiler in Xcode 4.2, а не об ARC - person IluTov; 07.12.2012
comment
@NSAddict stackoverflow.com/questions/9245317/ - person trojanfoe; 07.12.2012
comment
@trojanfoe О, не знал этого. Извини, я виноват. Так что сообщение, которое вы только что упомянули, объясняет это. - person IluTov; 07.12.2012