成員變數
1、成員變數的定義
ivar: 例項變數型別,是乙個指向objc_ivar結構體的指標
typedef struct objc_ivar *ivar;
2、相關函式
// 獲取所有成員變數
class_copyivarlist
// 獲取成員變數名
ivar_getname
// 獲取成員變數型別編碼
ivar_gettypeencoding
// 獲取指定名稱的成員變數
class_getinstancevariable
// 獲取某個物件成員變數的值
object_getivar
// 設定某個物件成員變數的值
object_setivar
說明:property_getattributes函式返回objc_property_attribute_t結構體列表,objc_property_attribute_t結構體包含name和value,常用的屬性如下:
屬性型別 name值:t value:變化
編碼型別 name值:c(copy) &(strong) w(weak)空(assign) 等 value:無
非/原子性 name值:空(atomic) n(nonatomic) value:無
變數名稱 name值:v value:變化
使用property_getattributes獲得的描述是property_copyattributelist能獲取到的所有的name和value的總體描述,如 t@"nsdictionary",c,n,v_dict1
3、例項應用
@inte***ce person : nsobject
@property(nonatomic,strong)nsstring *name;
@property(nonatomic,assign)nsinteger age;
//遍歷獲取person類所有的成員變數ivarlist
- (void) getallivarlist
free(ivars);
}201qoakvygxb6-06-15 20:26:39.412 demo-cocoa之method swizzle[17798:2565569] person擁有的成員變數的型別為@"nsstring",名字為 address
2016-06-15 20:26:39.413 demo-cocoa之method swizzle[17798:2565569] person擁有的成員變數的型別為@"nsstring",名字為 _name
2016-06-15 20:26:39.413 demo-cocoa之method swizzle[17798:2565569] person擁有的成員變數的型別為q,名字為 _age
屬性 1、屬性的定義
objc_property_t:宣告的屬性的型別,是乙個指向objc_property結構體的指標
typedef struct objc_property *objc_property_t;
2、相關函式
// 獲取所有屬性
class_copypropertylist
說明:使用class_copypropertylist並不會獲取無@property宣告的成員變數
// 獲取屬性名
property_getname
// 獲取屬性特性描述字串
property_getattributes
// 獲取所有屬性特性
property_copyattributelist
3、例項應用
@inte***ce person : nsobject
@property(nonatomic,strong)nsstring *name;
@property(nonatomic,assign)nsinteger age;
//遍歷獲取所有屬性property
- (void) getallproperty
}2016-06-15 20:25:19.653 demo-cocoa之method swizzle[17778:2564081] person擁有的屬性為: 'name'
2016-06-15 20:25:19.653 demo-cocoa之method swizzle[17778:2564081] person擁有的屬性為: 'age'
應用具體場景
1、json到model的轉化
在開發中相信最常用的就是介面資料需要轉化成model了(當然如果你是直接從dict取值的話。。。),很多開發者也都使用著名的第三方庫如jsonmodel、mantle或mjextension等,如果只用而不知其所以然,那真和「搬磚」沒啥區別了,下面我們使用runtime去解析json來給model賦值。
原理描述:用runtime提供的函式遍歷model自身所有屬性,如果屬性在json中有對應的值,則將其賦值。
核心方法:在nsobject的分類中新增方法:
- (instancetype)initwithdict:(nsdictionary *)dict
//立即釋放properties指向的記憶體
free(properties);
//(2)根據型別給屬性賦值
for (nsstring * key in keys)
} return self;
}讀者可以進一步思考:
如何識別基本資料型別的屬性並處理
空(nil,null)值的處理
json中巢狀json(dict或array)的處理
嘗試解決以上問題,你也能寫出屬於自己的功能完備的json轉model庫。
2、快速歸檔
有時候我們要對一些資訊進行歸檔,如使用者資訊類userinfo,這將需要重寫initwithcoder和encodewithcoder方法,並對每個屬性進行encode和decode操作。那麼問題來了:當屬性只有幾個的時候可以輕鬆寫完,如果有幾十個屬性呢?那不得寫到天荒地老.
原理描述:用runtime提供的函式遍歷model自身所有屬性,並對屬性進行encode和decode操作。
核心方法:在model的基類中重寫方法:
- (id)initwithcoder:(nscoder *)adecoder
} return self;
}- (void)encodewithcoder:(nscoder *)acoder
}3、訪問私有變數
我們知道,oc中沒有真正意義上的私有變數和方法,要讓成員變數私有,要放在m檔案中宣告,不對外暴露。如果我們知道這個成員變數的名稱,可以通過runtime獲取成員變數,再通過getivar來獲取它的值。
方法:ivar ivar = class_getinstancevariable([model class], "_str1");
nsstring * str1 = object_getivar(model, ivar);
寫給看客
對於已入行的程式設計師來說,刨根問底,挖開底層是突破瓶頸的必經之路。要想要從技術開發的普通工人變成真正的工程師,就必須需要啃下這塊骨頭。
而且在完成這篇文章的過程中,我發現自己之前走了不少彎路。因為底層理解不夠,在擴充套件學習時深感效率低下,過目即忘。歸根結底是只了解皮毛,無法內化,深入理解開發者的思路。
本文標題: runtime獲取屬性和成員變數方法
本文位址: /ruanjian/ios/220223.html
OC 的 Runtime 動態獲取物件屬性
執行時是 oc 的核心,其特點就是程式在執行的時候,以傳送訊息的形式呼叫方法.在實際開發中,關於執行時方面的運用點,其實並不多,最常用的也無非是動態獲取物件的屬性.示例 1.新建乙個繼承自nsobject 的物件,在.h 檔案宣告2個屬性 import inte ceperson nsobject ...
解析成員屬性和成員方法
解析成員方法 1 利用 method 執行方法 method物件提供了如下方法,用於執行它所代表的方法 public object invoke object obj,object.args 使用method 可以執行無參 有參 多個參 帶陣列和基本資料型別 靜態 私有的 方法。2 建立類的例項的兩...
解析成員屬性和成員方法
解析成員方法 1 利用method執行方法 method物件提供了如下方法,用於執行它所代表的方法 public object invoke object obj,object.args 使用method可以執行無參 有參 多個參 帶陣列和基本資料型別 靜態 私有的 方法。建立類的例項的兩種方法 1...