2016-05-04 4 views
0

Я получил SIGABRT, когда я присвоить значение свойству «myLocal» класса CMRequestManager в Singleton Init. Что не так?исключение SIGABR при попытке присвоить свойство в 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 

EDIT:

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

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

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

+0

см. Ths once http://stackoverflow.com/questions/14271421/exception-type-exc-crash-sigabrt –

+0

Вместо этой строки ** sharedMyManager = [[self alloc] init]; **, вы можете заменить он с ** sharedMyManager = [[CMRequestManager alloc] init]; **. просто догадайтесь, пожалуйста, попробуйте. – user3300864

+0

Я пробовал и делал ту же ошибку –

ответ

1
@interface CMRequestManager (private) 

Это ваша проблема. Что вы имели в виду:

@interface CMRequestManager() 

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

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

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

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

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

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