为什么我必须在 header 中声明由协议指定的 属性,而不是 class 扩展(实现)

Why do I have to declare a property specified by a protocol in the header, and not the class extension (implementation)

所以我有一个协议,它需要声明一个 属性:

@protocol MyProtocol <NSObject>
@property MyView *myView;
@end

和符合它的object:

@interface MyViewController : NSViewController <MyProtocol>
@end

但是,如果我在实现文件(class 扩展名)中声明 属性(在协议中指定):

@interface MyViewController()
@property MyView *myView;
@end

我收到这个错误:

Illegal redeclaration of property in class extension 'MyViewController' (attribute must be 'readwrite', while its primary must be 'readonly')

似乎有两个主要的 SO 线程解决了这个问题:
attribute must be readwrite while its primary must be read only

Can't declare another window

第一个答案没有说明任何问题

第二个答案说你实际上可以通过在 header 中声明 属性 来避免这个错误;唉

Header

@interface MyViewController : NSViewController <MyProtocol>
@property MyView *myView;
@end

实施

@interface MyViewController()
@end

此构建没有错误。

我也知道当你在协议中声明一个 @property 时,它不会自动合成。

所以如果我想在实现中保留 @property 声明,我将不得不 @synthesize 它。这也有效。


所以我的问题是,如果 @property 最初是在协议内部声明的,为什么在 header 内部声明 @property 与实现文件很重要?

没有协议,我认为唯一的区别是 @property public 或私有。但很明显,如果您在 header 中声明 @property 与实现文件

相比,还有其他事情 happen/don 不会发生

不要在 class 的任何地方声明 属性。它已经在协议中声明了。

不要将 @property MyView *myView; 放入 MyViewController.m 或 MyViewController.h 文件中。

要修复关于 "auto property synthesis" 的警告,您只需添加:

@synthesize myView = _myView;

MyViewController 实现或根据需要添加显式 getter 和 setter 方法。