0

当我在初始化SIGABRT中为类的属性“myLocal”赋值时,我得到了一个。怎么了?CMRequestManagerSingleton

 @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

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

4

1 回答 1

1
@interface CMRequestManager (private)

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

@interface CMRequestManager ()

这些看起来非常相似,但实际上却大不相同。首先是一个类别。您只是承诺存在这样的属性,但不会分配支持 ivar,也不会合成 getter 和 setter。你需要一个@implementation真正提供这些的地方。

如果您查看日志,您可能会看到“CMRequestManager 不符合 myLocal 的键值”或“CMRequestManager 不响应选择器 -myLocal”之类的内容。经常检查日志输出;答案经常在那里。

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

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

这在您移动属性时有效,因为您将其作为实际界面的一部分,这与将其放入扩展中所做的事情相同。

有关类别和扩展的更多讨论,请参阅使用 Objective-C 编程。

于 2016-05-04T20:34:50.743 回答