我经常很难决定是否应该通过属性或方法公开某些数据。你可以说“使用对象状态的属性”,但这不是很令人满意。以这个例子为例:
- (NSString *)stringOne
{
return _stringOne;
}
- (NSString *)stringTwo
{
return _stringTwo;
}
- (NSString *)mainString
{
return [_stringOne length] > 0 ? _stringOne : _stringTwo;
}
很明显,stringOne
和stringTwo
应该是属性,因为它们显然是对象状态。但是,如果mainString
应该是属性,则不清楚。最终用户mainString
就像状态一样。对于您的对象,mainString
不是状态。
这个例子是人为的,但希望你能得到这个想法。是的,属性只不过是创建getter和setter的便捷方式,但它们也向用户传达了一些信息。有没有人有适当的指导方针来决定何时使用财产与方法。
答案 0 :(得分:5)
隐藏“真实”状态(在您的示例中为string1
和string2
)和“动态”状态(mainString
)之间的分割,我会说,完全< / em>属性是什么。
规范示例可能是一个代表一个人的对象,给定的姓氏和姓氏为“状态”。可以从这两个部分呈现第三个状态“全名”,但是客户绝对没有理由知道全名是按需构建,还是在设置两个部分时创建和存储。这没关系。
属性是接口 - 此类为其客户端提供了哪些数据位(客户端可以配置哪些类)?每个属性的实现都是封装的,不会影响其作为属性的状态。
当然,在ObjC中,我们使用方法来访问属性。但是,其他方法表示对象可以采用的 actions ,可能传递一些数据来进行操作。
答案 1 :(得分:1)
要考虑的另一个考虑因素:您是否要存储该属性的值? (例如,通过NSCoding或核心数据) 我猜你需要为你需要“保存”的东西创建属性(例如在“encodeWithCoder”中。决定你想在encodeWithCoder中放置什么可以帮助你决定你想要定义的东西)。
对于您不需要保存并且可以轻松重新计算的内容,您可以在方法和只读属性之间进行选择(在引擎盖下等效:readonly属性仅创建getter访问器方法,并且没有支持它的实例变量)。所以这更像是一种风格问题。
说到样式,如果你只使用点符号作为属性(就像我一样),你可能会想: - 我是否要将全名作为foo.fullName访问,而不是与foo.firstName和foo.lastName等其他属性有所区别? - 或者你想通过[foo fullName]访问全名来改变世界,向全世界展示这是计算出来的吗?
我创建了一个用于跟踪股票报价的应用程序,该模型的灵感来自于Big Nerd Ranch关于Objective C的书中的一个例子(顺便说一句好读)。 以下是属性和方法的定义方式:
// properties
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *symbol;
@property (nonatomic, copy) NSString *currency;
@property (nonatomic, copy) NSString *market;
@property (nonatomic) int numberOfShares;
@property (nonatomic) double purchaseSharePrice;
@property (nonatomic) double currentSharePrice;
// Stock Calculation methods
- (double)costInLocalCurrency; // purchaseSharePrice * numberOfShares
- (double)valueInLocalCurrency; // currentSharePrice * numberOfShares
- (double)gainOrLossInLocalCurrency // valueInLocalCurrency - costInLocalCurrency
你可以看到它们清晰可辨。 BNR在他们的书中根本没有使用点符号,所以看起来都一样:[foo currentSharePrice]或[foo valueInLocalCurrency],但是当我使用点符号表示属性时,我会在foo之间改变风格。 currentSharePrice和[foo valueInLocalCurrency]。
希望这有用。
答案 2 :(得分:0)
按照设计,你应该始终尊重最终用户 - 如果你认为它是你班级用户的对象状态(显然是这样),那就继续从中获取一个属性。