尝试在单例中分配 属性 时出现 SIGABR 异常

SIGABR exception when try to assign a property in a Singleton

当我为 class [=] 属性 "myLocal" 赋值时,我得到了 SIGABRT 14=] 在 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" 移动到 class 扩展名之外:

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

这项工作,但我不明白为什么。所以问题仍然存在:我之前的代码有什么问题?

@interface CMRequestManager (private)

这是你的问题。你的意思是:

@interface CMRequestManager ()

这些看起来很相似,但实际上却大不相同。第一个是类别。您只是承诺存在这样的 属性,但不会分配任何支持 ivar,也不会合成任何 getter 和 setter。你需要一个 @implementation 块来实际提供这些。

如果您查看日志,您可能会看到 "CMRequestManager not key-value compliant for myLocal" 或 "CMRequestManager does not respond to selector -myLocal" 之类的内容。经常检查日志输出;答案通常就在那里。

第二种形式 () 是扩展。扩展是 class 定义的延续。在那里定义的属性将自动接收存储和合成的 getter 和 setter。

这两者之间的差异具有很强的历史性。类别形式自 ObjC 早期就已存在,早在属性被添加到语言之前(它最初是一种为大型复杂对象拆分接口的方法,后来主要成为一种创建 "protected"或 "friend" 方法)。扩展形式是最近添加的,看起来像我们习惯的类别,同时提供了 ObjC 2 附带的一些额外功能(如属性和合成方法)。

这在您移动 属性 时起作用,因为您使它成为实际界面的一部分,这与将它放在扩展中的效果相同。

有关类别和扩展的更多讨论,请参阅 Programming with Objective-C