一. 屬性肺素,成員變量,實例變量
在討論之前我先給大家推薦一個 NSObject 的類擴(kuò)展 NSObject+DLIntrospection 利用 runtime宇驾,擴(kuò)展了獲取類的屬性倍靡,實例變量,實例方法课舍,類方法塌西,協(xié)議protocol 等列表的方法,后面的講解我們需要用到它布卡。
#import <Foundation/Foundation.h>
@interface NSObject (DLIntrospection)
+ (NSArray *)classes; // 獲取所有的類名
+ (NSArray *)properties; // 獲取屬性列表
+ (NSArray *)instanceVariables; // 獲取實例變量列表
+ (NSArray *)classMethods; // 獲取類方法列表(+方法)
+ (NSArray *)instanceMethods; // 獲取實例方法列表(-方法)
+ (NSArray *)protocols; // 獲取協(xié)議列表
+ (NSDictionary *)descriptionForProtocol:(Protocol *)proto;
+ (NSString *)parentClassHierarchy; // 當(dāng)前類的繼承關(guān)系
@end
廢話少說雨让,先看代碼
.h 源碼
@interface HMTestClass : NSObject
{
NSString *_ivarInterface; // 實例變量,在iOS開發(fā)中也叫成員變量
}
@property (nonatomic, copy) NSString *propertyInterface;
@end
再看 .m 源碼
@interface HMTestClass ()
@property (nonatomic, copy) NSString *propertyImplementation;
@end
@implementation HMTestClass
{
NSString *_ivarImplementation; // 實例變量忿等,在iOS開發(fā)中也叫成員變量
}
@end
最后咱們看看調(diào)試輸出結(jié)果
// 獲取屬性輸出結(jié)果
(lldb) po [HMTestClass properties]
<__NSArrayI 0x100200c40>(
@property (nonatomic, copy) NSString* propertyImplementation,
@property (nonatomic, copy) NSString* propertyInterface
)
// 獲取實例變量輸出結(jié)果
(lldb) po [HMTestClass instanceVariables]
<__NSArrayI 0x100300430>(
NSString* _ivarInterface,
NSString* _ivarImplementation,
NSString* _propertyInterface,
NSString* _propertyImplementation
)
看到這里栖忠,我們首先可以得出結(jié)論:
- 屬性 即用 @property 聲明的部分,它可以在 .h 文件里贸街,也可以在 .m 文件里庵寞,在 .m 里即為私有屬性;
- 而 實例變量 即為被包含在 @interface 和 @implementation 下的大括號里的薛匪,以及 @property 時編譯器為我們自動生成的兩部分組成捐川;
我們還看到用 @property 聲明的屬性 propertyInterface 和 propertyImplementation,編譯器自動給我們生成了對應(yīng)以下劃線 _ 開頭的 實例變量逸尖,這一部分也是個學(xué)問古沥,后一部分再講
關(guān)于 成員變量 我認(rèn)為就是 實例變量,兩者等價娇跟,又或者僅僅只是 @interface 下的部分岩齿。
當(dāng)然有官方更準(zhǔn)確的描述的,非常非常歡迎感謝前來指正0m锷颉!
概括一下:
咱們用比喻的修辭手法來說吃谣,屬性 是個口袋乞封,屬性名稱描述它是上衣口袋,褲兜岗憋,還是其他位置的口袋肃晚,沒有有實際意義,只讓外界看到有一個口袋仔戈,當(dāng)然口袋也可以縫在里面(在 .m 文件里聲明)陷揪,只有自己知道惋鸥,當(dāng)然放在外面的,也有可能只是看起來像個口袋悍缠,不能裝東西(.m 里使用了 @dynamic 但忘記自己實現(xiàn) set get卦绣,后面再詳細(xì)介紹),而 實例變量 就是在口袋里存放的實實在在的東西飞蚓。
二. @property滤港,@synthesize,@dynamic
-
@property
- 屬性聲明關(guān)鍵字趴拧,有三個類別的關(guān)鍵詞分別描述該屬性的:線程限制溅漾,內(nèi)存管理,讀寫權(quán)限三方面的表現(xiàn)著榴,默認(rèn)情況下添履,基本數(shù)據(jù)類型為 atomic, assign, readwrite,OC 對象為 atomic, strong, readwrite
- 若 .m 文件不使用 @synthesize 和 @dynamic脑又,編譯器會自動生成屬性的 set get 方法暮胧,并生成 已下劃線 _ 加屬性名的實例變量;
-
@synthesize
- @synthesize property; 這種情況下问麸,編譯器生成的實例變量沒有了下滑下往衷;
- @synthesize property = _ivar; 這種情況下,編譯器不再生成實例變量严卖,對 property 調(diào)用set get 實際操作的是 _ivar 實例變量席舍,即這個口袋里放的是 _ivar;
- @dynamic
- @dynamic property; 編譯器不會生成實例變量,同時也不會實現(xiàn) set get 方法哮笆,需要開發(fā)者自己手寫来颤,如若忘記自己實現(xiàn) set get,碰到對 set get 進(jìn)行的調(diào)用的地方稠肘,程序會 crash福铅,報unrecognized selector的異常
end