在接口中覆盖Objective-c协议属性属性;最佳实践?

时间:2014-04-02 03:30:19

标签: objective-c properties attributes protocols

如果在协议中定义具有属性的属性,例如:

@protocol ExampleProtocol <NSObject>

@property NSString * test0;

@property NSString * test1;

@property (weak, nonatomic) NSString * test2;

@property (weak, atomic) NSString * test3;

@end

然后在界面中“覆盖”这些属性,例如:

@interface Example : SKLabelNode <ExampleProtocol>

@property NSString * test0; // No warnings

@property (strong, atomic) NSString * test1; // No warnings

@property (strong, atomic) NSString * test2; // Warns about both strong and atomic

@property (strong, nonatomic) NSString * test3; // Warns about both strong and atomic

@end

当属性不匹配时,您会收到编译器警告,而不是错误。

我不是专家,但看着程序集向我表明界面中的属性是“赢”的属性。

因此,最佳做法是省略协议属性的属性,除非您知道它们始终是协议合同的一部分吗?

1 个答案:

答案 0 :(得分:0)

*忽略这样一个事实,即将属性声明放在​​协议中通常是一个坏主意,更不用说弱属性了。

覆盖这样的属性声明的问题,或者至少是编译器对你的重写,是你重新声明该协议的后备变量的存储修饰符(或者将会是什么)稍后由符合该协议的类别确定。编译器不能,而且坦率地说不应该保证它最终会最终生成代码的两个修饰符中的哪一个,因此它会发出警告。弱变量与强变量是非平凡可转换的,并且在编译时可能对任何试图使用您的代码的人都不明确。编译器可以保证的是原子串访问器不会发出警告。所需要的只是在主类中生成本地同步的getter。

正如您自己提到的,协议类似于合同。声明属性没有意义,因为@property指令指示了在对象上创建新属性所需的所有合成方式。最多,您所做的是强制实施者改变他们的支持变量,最糟糕的是,您已经创造了潜在的漏洞。只需在协议中声明setter和getters sans指令,或者然后生成实现类的实际属性。无论如何,对于协议来说这是非常不寻常的严格读写。