Исключение 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 для более подробного обсуждения категорий и расширений.