iOS 之通過反射機制獲得變數名

2021-06-28 16:23:38 字數 1688 閱讀 2968

專案有的時候,會遇到一些特殊的處理,想要根據乙個例項的引用,獲取這個例項在**中的名稱。比如在處理view的座標的時候,我們將uiview的座標資訊配置到plist檔案中,我們可以設定乙個key,再通過這個key來獲取配置檔案中的座標等資訊。有沒有更簡單的方法呢,或者我只想簡單的用例項變數的變數名做為key。下面就介紹一種簡單的,根據例項變數的引用獲取例項變數名的辦法。

第一步,我們需要引入我們需要的標頭檔案,在需要使用的類中引用下面**

[cpp]view plain

copy

#import 

我們可以從蘋果官方的開發文件中檢視到詳細的執行時的使用方法及api,官方並沒有直接提供根據例項的引用獲取例項變數名稱的辦法,所以我們需要自己去實現。

在官方的api中我們可以找到以下幾個方法

(1)describes the instance variables declared by a class.    

ivar * class_copyivarlist(class cls, unsigned int *outcount)

(2)reads the value of an instance variable in an object.

id object_getivar(id object, ivar ivar)
(

3) returns the name of an instance variable.

const char * ivar_getname(ivar ivar)
根據以上的api,我們可以根據變數的擁有者獲取所有變數的ivar,再迭代所有ivar,每一次迭代做如下操作

(1)根據上面的原理我們可以得到第一版本的**,如下:

[cpp]view plain

copy

- (nsstring *)namewithinstance:(id)instance  

}   

free(ivars);  

return

key;  

}  

(2)在測試中發現到達上面的if語句的時候,程式有的時候就會crash,經詳細測試發現,每次迭代到非objective-c物件的時候,如基本資料型別,bool、int、float就會報錯。

原因出在object_getivar這個方法中,當遇到非objective-c物件時,

並直接crash,後來檢視官方解釋

the value of the instance variable specified by ivar, or nil if object is nil.
並沒有明確的給出遇到非物件時會crash,也並不會返回nil

我們需要進行一下修正,當遇到非objective-c的時候,需要跳過執行。最終**如下:

[cpp]view plain

copy

- (nsstring *)namewithinstance:(id)instance  

if((object_getivar(self.target, thisivar) == instance))   

}  free(ivars);  

return

key;  

}

通過反射將變數值轉為變數名本身ZZ

這是.net反射的乙個有趣小例子 通過反射將變數值轉為變數名本身.當然要先新增命名空間 using system.reflection 示例 如下 class program 獲取所有fieldinfo的值 void gettypevalue console.writeline 獲取字串str對應的...

python反射技術使用(動態變數名)

需求 需要通過動態變數名,取得對應的值。例如,定義有如下類 也許是自己設計的表結構不合理 時不時需要獲取或設定變數 env 變數的值然後更新資料庫,所以急需使用變數名的變數,要不就需要寫一堆判斷語句 發布單 model class order models.model current env mod...

iOS開發之 巧用反射機制

1 應用場景 自定義uitabbarcontroller的tabbar檢視 1 隱藏tabbar檢視 一般我們選擇自定義tabbar檢視有兩種方式。1是將tabbar檢視隱藏 2是將tabbar檢視從父檢視中移除,如下 假設,已建立uitabbarcontroller子類 void viewdidl...