7

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

- (NSString *)stringOne
{
    return _stringOne;
}

- (NSString *)stringTwo
{
    return _stringTwo;
}

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

很明显,stringOne并且stringTwo应该是属性,因为它们显然是对象状态。但是,尚不清楚是否mainString应该是属性。对最终用户mainString来说就像状态一样。对你的对象,mainString 不是状态。

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

4

3 回答 3

5

我会说,隐藏“真实”状态(在您的示例中)和“动态”状态()之间的分裂string1正是string2属性用途。mainString

典型的例子可能是一个代表一个人的对象,名字和姓氏作为“状态”。第三个状态,“全名”可以从这两个部分呈现,但是客户完全没有理由知道全名是按需构建的,还是在设置两个部分时创建和存储的。根本没关系。

属性是一个接口——这个类向它的客户端提供了哪些数据(以及客户端可以对这个类进行什么配置)?每个属性的实现都是封装的,不影响其作为属性的状态。

当然,在 ObjC 中,我们使用方法来访问属性。然而,其他方法表示对象可以执行的操作,可能会传递一些数据以进行操作。

于 2012-08-19T21:11:01.947 回答
1

另一个要考虑的因素:你想存储财产的价值吗?(例如通过 NSCoding 或在 Core Data 中)我想您需要为需要“保存”的内容创建属性(例如在“encodeWithCoder”中。决定要放入 encodeWithCoder 的内容可以帮助您决定要以哪种方式保存)定义事物)。

对于不需要保存并且可以轻松重新计算的东西,您可以在方法和只读属性之间进行选择(这在引擎盖下是等效的:只读属性只创建一个 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]。

希望这会有所帮助。

于 2013-12-28T10:42:42.150 回答
0

按照设计,您应该始终尊重最终用户 - 如果您认为它是您的类用户的对象状态(显然是),那么继续并从中创建一个属性。

于 2012-08-19T20:58:44.003 回答