runtime獲取屬性和成員變數方法

2022-09-21 14:21:09 字數 3661 閱讀 9223

成員變數

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...