使用属性与方法的指南

时间:2012-08-19 20:51:51

标签: objective-c properties methods

我经常很难决定是否应该通过属性或方法公开某些数据。你可以说“使用对象状态的属性”,但这不是很令人满意。以这个例子为例:

- (NSString *)stringOne
{
    return _stringOne;
}

- (NSString *)stringTwo
{
    return _stringTwo;
}

- (NSString *)mainString
{
    return [_stringOne length] > 0 ? _stringOne : _stringTwo;
}

很明显,stringOnestringTwo应该是属性,因为它们显然是对象状态。但是,如果mainString应该是属性,则不清楚。最终用户mainString就像状态一样。对于您的对象,mainString 不是状态。

这个例子是人为的,但希望你能得到这个想法。是的,属性只不过是创建getter和setter的便捷方式,但它们也向用户传达了一些信息。有没有人有适当的指导方针来决定何时使用财产与方法。

3 个答案:

答案 0 :(得分:5)

隐藏“真实”状态(在您的示例中为string1string2)和“动态”状态(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)

按照设计,你应该始终尊重最终用户 - 如果你认为它是你班级用户的对象状态(显然是这样),那就继续从中获取一个属性。