淺談Categroy不能為原類新增Property的原因
在日常的開發當中我們經常使用Category來處理一些問題,但是Category有個蛋疼的事,不能為原類新增屬性。瞭解過Runtime的小夥伴都知道,我們可以利用runtime來解決這個問題。但是今天我們來了解一下Category為什麼不能為原類新增屬性。
我們先來建立一個Book類,定義一個屬性BookName。
@interface Book : NSObject
@property (nonatomic, copy) NSString *bookName;
@end
再來建立一個分類,定義一個屬性。
@interface Book (Property)
@property (nonatomic, copy) NSString *author;
@end
這裡大家要先了解一下屬性的構成
Property(屬性) = ivar(例項變數) + setter + getter
接下來我們可以利用runtime來列印一下。
//獲取類的成員變數
- (void)getClassIvars {
unsigned int count;
//獲取成員變數的陣列的指標
Ivar *ivars = class_copyIvarList([Book class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
//根據ivar獲得其成員變數的名稱
const char *name = ivar_getName(ivar);
//c的字串轉oc的字串
NSString *key = [NSString stringWithUTF8String:name];
NSLog(@"ivar__%d == %@",i,key);
}
//記得釋放
free(ivars);
//如果你的成員私有,也可以獲取到 比如_education
}
//獲取類的成員屬性
- (void)getClassProperty {
unsigned int count;
//獲得指向該類所有屬性的指標
objc_property_t *properties = class_copyPropertyList([Book class], &count);
for (int i = 0; i < count; i++) {
//獲取該類的一個屬性的指標
objc_property_t property = properties[i];
//獲取屬性的名稱
const char *name = property_getName(property);
//將c的字串轉化為OC字串
NSString *key = [NSString stringWithUTF8String:name];
NSLog(@"propertyLabel__%d == %@",i,key);
}
//記得釋放
free(properties);
}
列印結果
2017-02-22 14:57:21.218 DDTool[1757:134117] ivar__0 == _bookName
2017-02-22 14:57:21.219 DDTool[1757:134117] property__0 == author
2017-02-22 14:57:21.219 DDTool[1757:134117] property__1 == bookName
2017-02-22 14:57:21.219 DDTool[1757:134117] method__0 == bookName 2
2017-02-22 14:57:21.219 DDTool[1757:134117] method__1 == setBookName: 3
2017-02-22 14:57:21.219 DDTool[1757:134117] method__2 == .cxx_destruct 2
- 這裡我們可能有一個疑惑,pro_list列印的結果中不是有author這個屬性麼(這個下面會說,我們先觀察重點),我們發現ivar_list列印的結果中只有_bookName這個例項變數,沒有_author。這樣我們就可以大概知道為什麼新增不了屬性了,沒有滿足屬性的構成條件。
- 接著上面的疑問來講,其實這裡列印的pro_list並非是上文所述的屬性,它只是一個屬性的描述。這裡看到其他的部落格上有講到:
每次在增加一個屬性,系統都會在ivar_list中新增一個成員變數的描述,在method_list中增加setter與getter方法的描述,在pro_list中增加一個屬性的描述,然後計算該屬性在物件中的偏移量,然後給出setter與getter方法對應的實現。
至於Category為什麼沒有生成ivar,是因為分類本身並不是一個真正的類,它並沒有自己的isa。
以上是自己在查閱資料後的一些淺層理解,不正確的、不足的地方還有望指出。?
相關文章
- 使用property為類中的資料新增行為
- 淺談 Swift 中的屬性(PropertySwift
- 淺談 Swift 中的屬性(Property)Swift
- 遊戲漫談:淺談為何《博德之門3》和拉瑞安會獲得成功的原因遊戲
- 類的property特性
- 淺談 Dart 類與類的基本方法Dart
- 淺談:js後加?v=版本號的原因JS
- 淺談伺服器價格不同的原因伺服器
- 淺談 Trait 類AI
- 淺談Java抽象類Java抽象
- 淺談Java中的內部類Java
- 淺談java內部類Java
- 【原創】淺談指標(一)指標
- 【原創】淺談指標(二)指標
- 【原創】淺談指標(三)指標
- 【原創】淺談指標(四)指標
- 淺談 PHP 中異常類的使用PHP
- 人工智慧分類淺談人工智慧
- 不能為 EXTERNAL REDUNDANCY的磁碟組新增failgroup diskAI
- (原)淺談採購業務規劃
- 原因定位:Oracle為何不能使用索引(轉)Oracle索引
- 聲名顯赫為何慘遭雪藏?淺談《惡魔城》系列沉淪原因
- 深度聚類演算法淺談聚類演算法
- iOS使用Category新增@property變數iOSGo變數
- [原創]淺談勝新系列軟體的破解
- [原創]淺談大資料測試大資料
- 淺談遊戲內攝影模式的流行原因與發展潛力遊戲模式
- 淺談限流元件的應用和設計原則元件
- 淺談MFC中超類化技術的實現 (轉)
- 【原創】淺談指標(十一)alloca函式指標函式
- [原創]淺談移動App安全測試APP
- 為普通Object新增類似AttachedProperty的屬性Object
- 淺談電商養成類遊戲選型策略遊戲
- 淺談SAP期末清帳和重分類
- 異常org.hibernate.QueryException: could not resolve property的原因Exception
- 【原創】淺談指標(十三)指向陣列的指標指標陣列
- 【原創】淺談指標(十)連結串列的寫法指標
- 淺談J2EE開發 之 易用的原則