[英]In Objective-C does it make sense to declare a readonly property in a category?
假設我有Tree.h
和Tree+Extensions.h
。 我知道如果我在Tree+Extensions.h
聲明@property (nonatomic) NSString *color
然后訪問它,它將崩潰,並且我可以使用objc_getAssociatedObject
和objc_setAssociatedObject
獲得類似於該功能的東西。
但是,我也看到了這個:
// Tree+Extensions.h
@interface Tree (Extensions)
@property (nonatomic, readonly) NSString *color;
@end
// Tree+Extensions.m
@implementation Tree (Extensions)
- (NSString *)color {
return @"green";
}
@end
請注意,類別中的屬性聲明為readonly
,並且accessor方法返回可以計算的內容。
我已經看到這個代碼工作了,但是想知道為什么這比僅僅在頭文件中聲明訪問器方法更可取。
讓我們首先忽略這是一個類別並且只是談論這個事實:
@interface Tree
@property (nonatomic, readonly) NSString *color;
@end
@implementation Tree
- (NSString *)color {
return @"green";
}
@end
據我了解,你的問題是:它與此之間的區別是什么:
@interface Tree
- (NSString *)color;
@end
@implementation Tree
- (NSString *)color {
return @"green";
}
@end
從完全實用的角度來看, 沒有區別。 人們習慣於聲明屬性,但實際上這兩個聲明具有完全相同的效果 - 即,在任何一種情況下,調用者(任何已導入界面的人)都可以[aTree color]
說[aTree color]
或aTree.color
。 屬性用法( aTree.color
) 是方法調用[aTree color]
,反之亦然。 即使只聲明了color
方法 (不是屬性),調用者也可以說 aTree.color
。 這就是為什么,例如,說myArray.count
是合法的(和常見的),即使NSArray的count
沒有被聲明為屬性(它只是一個方法)。 反之亦然 ,即使將navigationController
聲明為屬性,也可以說[myViewController navigationController]
是合法的(也是常見的)。
現在,在大多數情況下,聲明屬性的原因是為了讓編譯器合成相應的實例變量和相應的方法實現。 但在這種情況下,這一切都沒有發生; 沒有實例變量,也沒有要合成的getter(已經明確寫過)。
因此,總而言之,讓我們現在回到原始問題並總結:您不能使用命名類別(如Tree (Extensions)
)將實例變量添加到現有類。 正如Apple所說 :
在類別接口中包含屬性聲明是有效的語法,但是不可能在類別中聲明其他實例變量。 這意味着編譯器不會合成任何實例變量,也不會合成任何屬性訪問器方法。
好吧,在這種情況下,你不是在現有類中添加一個實例變量,而你並沒有嘗試合成“getter”: readonly
屬性聲明由現有的 “getter”方法支持,正如你正確地說的那樣,計算整塊布料的結果。 因此,財產聲明雖然毫無意義,但卻完全合法有效:它只是聲明了“吸氣”方法。
使用您編寫的代碼,即使是在類中,您也無法調用setColor:
當您想要返回未被ivar支持的內容(例如計算)並且您不想要時,這可能是有意義的揭露外面的世界。
答:這是首選,因為您不需要從課外訪問此屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.