Исключение SIGABR при попытке назначить свойство в синглтоне

У меня есть SIGABRT когда я присваиваю значение свойству "myLocal" класса CMRequestManager в Singleton В этом. В чем дело?

 @interface CMRequestManager (private)
        @property (nonatomic,strong)  NSString* myLocal;
 @end

 @implementation CMRequestManager
        #pragma mark Singleton Methods
        + (id)Manager {
            static CMRequestManager *sharedMyManager = nil;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                sharedMyManager = [[self alloc] init];
                sharedMyManager.myLocal = @"test test"; //SIGABRT !!!!
            });
            return sharedMyManager;
        }

        - (id)init {
            if (self = [super init]) {

            }
            return self;
        }
 @end

РЕДАКТИРОВАТЬ:

Хорошо, я нашел решение: переместить свойство "myLocal" в заголовочный файл за пределы расширения класса:

 @interface CMRequestManager 
 @property (nonatomic,strong)  NSString* myLocal;
 @end

Это работа, но я не понимаю почему. Таким образом, остается вопрос: что не так в моем предыдущем коде?

1 ответ

Решение
@interface CMRequestManager (private)

Это твоя проблема. То, что вы имели в виду, было:

@interface CMRequestManager ()

Они выглядят очень похожими, но на самом деле они совсем другие. Первая категория. Вы просто обещаете, что такое свойство существует, но никакой резервный ivar не будет выделяться, и никакие геттеры и сеттеры не будут синтезироваться. Тебе нужен @implementation заблокировать где-то, что на самом деле это.

Если вы посмотрите на ваши журналы, вы, вероятно, увидите что-то вроде "CMRequestManager не соответствует значению ключа для myLocal" или "CMRequestManager не отвечает на селектор -myLocal" или что-то в этом роде. Всегда проверяйте вывод журнала; ответ очень часто там.

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

Разница между этими двумя очень историческая. Форма категории существовала с первых дней существования ObjC, задолго до того, как в язык были добавлены свойства (изначально это был способ разделения интерфейсов для больших и сложных объектов, а позднее стал главным способом создания "защищенных" или "защищенных"). друг "методы). Форма расширения является более поздним дополнением и сделана так, чтобы выглядеть как категории, к которым мы привыкли, при этом предоставляя некоторые дополнительные функции, которые пришли с ObjC 2 (например, свойства и синтезированные методы).

Это работает, когда вы перемещаете свойство, потому что вы сделали его частью реального интерфейса, что то же самое, что сделать его в расширении.

См. Программирование с Objective-C для более подробного обсуждения категорий и расширений.

Другие вопросы по тегам