财产与否?

时间:2014-01-16 15:12:57

标签: ios objective-c properties

关于语义的快速问题:)

如果我正在编写一个首选的协议:

// (a)
@protocol MyProtocol 

@property (nonatomic, copy) NSSet *things; 

@end

VS

// (b)
@protocol MyProtocol

- (NSSet *)things;
- (void)setThings:(NSSet *)things;

@end

(a)是更清晰的代码,但暗示实现类将具有things的ivar,而在我的项目中并非如此。由于我的用例,things也不能是KVO。它还意味着实现类将copy things,它在每种情况下都不适用于我。

(b)是更准确的代码(它非常清楚你能做什么/不做什么,即没有KVO),但它有点麻烦。

有什么意见吗?

3 个答案:

答案 0 :(得分:3)

我正在修改我的回答:(a)可能不是最适合协议,但最适合非协议接口。

我会选择@property。如何实现属性是一个实现细节,我从不考虑从外部。

考虑一个v1实现,其中属性只是那个。在v2中,内部组件被更改,并且setter或getter成为一种方法。完全合理,其中一个原因是属性是好的,它们允许这样的更改,它们隐藏了实现细节。

另外考虑相反的情况,在下一个版本中,需要删除方法并用属性替换它们。同样是第一个实例中的属性非常好的实现细节。

最后,在这种情况下,有一个copy属性,它提供了如何处理带有可变对象的调用的明确信息,这在方法实现中会丢失。

答案 1 :(得分:0)

我认为案例'a'会产生错误的信息:采用协议的类MyProtocol可以遵循非规则和复制的规则。

对我来说,在协议中添加属性非常奇怪。它反对面向对象编程的范式:代表们做一些行动,而不是提供信息。

所以我建议你不要使用'a'和'b'的情况,而是再考虑一下你的程序架构。

答案 2 :(得分:0)

协议定义消息传递合同[1]。它们不用于存储数据。根据Apple文档,您只应向类扩展添加属性(您可以向类别添加属性,但编译器不会合成ivar)[2]。根据您的尝试,我将使用以下两种方法之一与Objective-C语言的文档使用一致:

  
      
  1. 如果你有类的源代码(你创建的那个),那么使用类扩展。

  2.   
  3. 如果您没有源代码子类对象。

  4.   

话虽如此,如果你真的需要这样做,那么使用选项(b)。它更核心,更正确 更清洁的代码!

以下是处理同一问题的另一个question

祝你好运