Как решить «нераспознанный селектор, отправленный на экземпляр»? - PullRequest
36 голосов
/ 14 мая 2009

В AppDelegate я выделяю экземпляр, определенный в статической библиотеке. Этот экземпляр имеет свойство NSString, устанавливающее «копию». Когда я получаю доступ к свойству string в этом экземпляре, приложение вылетает с «нераспознанным селектором, отправленным экземпляру». Xcode предоставляет подсказку кода для свойства, что означает, что оно известно в вызывающем приложении. Определенный класс компилируется в статическую библиотечную цель. Чего мне не хватает?

Добавление некоторого кода.

//static library 
//ClassA.h
@interface ClassA : NSObject {
...
NSString *downloadUrl;
}
@property(nonatomic, copy) NSString *downloadUrl;

//ClassA.m
@synthesize downloadUrl;

В приложении вызывающего приложения Delegate.

//app delegate header file
@interface myApp : NSObject <UIApplicationDelegate> {
ClassA *classA;
}
@property (nonatomic, retain) ClassA *classA;

//app delegate .m file
@synthesize classA;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
classA = [[ClassA alloc] init];
//exception occurs here.  downloadUrl is of type NSCFNumber
classA.downloadUrl = @"http://www.abc.com/";
...}

Другие классы в приложении получат ссылку на делегат и вызовут classA.downloadUrl.

Ответы [ 9 ]

26 голосов
/ 14 мая 2009

1) Синтез в блоке @implementation?

2) Если вы ссылаетесь на self.classA = [[ClassA alloc] init]; и self.classA.downloadUrl = @"..." вместо простого classA?

3) В ваш файл myApp.m необходимо импортировать ClassA.h, если он отсутствует, по умолчанию он будет числом или указателем? (в переменных C по умолчанию используется значение int, если оно не найдено компилятором):

#import "ClassA.h".

18 голосов
/ 23 июля 2010

Установить флаг -ObjC в Другой флаг компоновщика в настройках вашего проекта ... (Не в проекте статической библиотеки, а в проекте, который использует статическую библиотеку ...) И убедитесь, что в проекте настройка Конфигурация установлена ​​на Вся конфигурация

15 голосов
/ 07 мая 2012

Многие люди дали несколько очень технических ответов на этот и подобные вопросы, но я думаю, что это проще, чем это. Иногда, если вы не обращаете внимания, к интерфейсу может быть прикреплен селектор, который вы не собираетесь использовать. Возможно, вы получаете эту ошибку, потому что селектор есть, но вы еще не написали код для него.

Самый простой способ перепроверить, что это не так, - это щелкнуть по элементу управления, чтобы вы могли увидеть все селекторы, связанные с ним. Если там есть что-то, чем ты не хочешь быть, избавься от этого! Надеюсь, это поможет ...

1 голос
/ 19 августа 2012

У меня было что-то простое / глупое. Ошибка новичка для любого, кто преобразовал свой NSManagedObject в обычный NSObject.

У меня было:

@dynamic order_id;

когда я должен был:

@synthesize order_id;
1 голос
/ 19 июня 2012

Для меня причиной этой ошибки было то, что я случайно дважды отправлял одно и то же сообщение одному и тому же ученику. Когда я щелкнул правой кнопкой мыши на кнопке в графическом интерфейсе, я смог дважды увидеть название метода и просто удалил один. В моем случае ошибка новичка наверняка, но я хотел, чтобы ее рассмотрели другие новички.

1 голос
/ 14 мая 2009

Как вы импортируете ClassA в свой класс AppDelegate? Вы включили файл .h в основной проект? У меня была эта проблема некоторое время, потому что я не копировал заголовочный файл в основной проект, а также обычный #include "ClassA.h".

Копирование или создание .h решило это для меня.

1 голос
/ 14 мая 2009

В коде, который вы разместили, вы отправляете установщик setDownloadURL: на ClassA, то есть сам класс Вы хотите установить свойство экземпляра.

0 голосов
/ 06 декабря 2010

Очень странно, но. Вы должны объявить класс для вашего экземпляра приложения как myApplication: UIApplication вместо myApplication: NSObject. Кажется, что протокол UIApplicationDelegate не реализует сообщение + registerForSystemEvents. Сумасшедшие Apple API, снова.

0 голосов
/ 08 июня 2009

Вы должны заметить, что это не обязательно лучший шаблон дизайна. Судя по всему, вы, по сути, используете свой делегат приложений для хранения того, что составляет глобальную переменную.

Мэтт Галлахер подробно рассмотрел вопрос о глобалах в своей статье «Какао с любовью» на стр. http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html.. По всей вероятности, ваш ClassA должен быть единичным, а не глобальным в AppDelegate, хотя вполне возможно, что ClassA вы хотите более общего назначения, а не просто синглтон. В этом случае вам, вероятно, будет лучше использовать метод класса для возврата предварительно сконфигурированного экземпляра класса A, например:

+ (ClassA*) applicationClassA
{
    static ClassA* appClassA = nil;
    if ( !appClassA ) {
        appClassA = [[ClassA alloc] init];
        appClassA.downloadURL = @"http://www.abc.com/";
    }
    return appClassA;
}

Или, в качестве альтернативы (поскольку это добавит специфичные для приложения вещи к тому, что, возможно, является классом общего назначения), создайте новый класс, единственная цель которого состоит в том, чтобы содержать этот метод класса.

Дело в том, что глобалы приложений не обязательно должны быть частью AppDelegate. Тот факт, что AppDelegate является известным одноэлементным, не означает, что любое другое глобальное приложение должно быть смешано с ним, даже если они не имеют никакого концептуального отношения к обработке методов делегата NSApplication.

...