objective c小貼條(一)

2021-06-20 20:23:15 字數 3846 閱讀 3745

objective-c 2.0 中增加了@dynamic 指令,表示變數對應的屬性訪問器方法,是動態實現的,你需要在nsobject 中繼承而來的+(bool) resolveinstancemethod:(sel) sel 方法中指定動態實現的方法或者函式。

@inte***ce person : nsobject  

-(person*) initwithweight: (int) weight;

@property (retain,readwrite) nsstring* name;

@property (readonly)float weight;

@property float height;

-(void) print: (nsstring*) str;

@end

void dynamicmethod(id self,sel _cmd,float w)  

@implementation person

@synthesize name;

@synthesize weight;

@dynamic height;

-(person*) initwithweight: (int) w

return self;

} -(void) print: (nsstring*) str

+(bool) resolveinstancemethod: (sel) sel

return result;

} -(void) dealloc

@end

這裡我們對於介面中的height在實現類中使用了@dynamic指令,緊接著,你需要指定乙個函式或者其他類的方法作為height的setter、getter方法的執行時實現。為了簡單,我們指定了person.m中定義的函式(注意這是c語言的函式,不是objective-c的方法)dynamicmethod

作為height的setter方法的執行時實現。被指定為動態實現的方法的dynamicmethod的引數有如下的要求:

a.第乙個、第二個引數必須是id、sel;

b.第三個引數開始,你可以按照原方法(例如:setheight:(float))的引數定義。

再接下來,你需要覆蓋nsobject 的類方法resolveinstancemethod,這個方法會把需要動態實現的方法(setheight:)的選擇器傳遞進來,我們判斷一下是否是需要動態實現的選擇器,如果是就把處理權轉交給dynamicmethod。如何轉交呢?這裡我們就要用到執行時函式class_addmethod(class,sel,imp,char)。

言歸正傳,我們來解釋一下這裡需要用到的class_addmethod 方法,這個方法有四個引數,class 表示你要為哪個型別增加方法,sel 引數表示你要增加的方法的選擇器,imp 表示你要新增的方法的執行時的具體實現的函式指標。其實在這裡你能夠看出sel 並不能在執行時找到真正要呼叫的方法,imp 才可以真正的找到實現方法的。

現在我們來正式的看以下第四個引數v@:f 的含義,它描述了imp 指向的函式的描述資訊,按照@encode 指令編譯之後的字元說明,第乙個字元v 表示返回值為void,剩餘的字元為dynamicmethod 函式的引數描述,@表示第乙個引數id,:自然就是第二個引數sel,f 就是第三個引數float。由於前面說過動態方法的實現的前兩個引數必須是id、sel,所以第四個引數中的字串的第

二、三個字元一定是@:。我們看到resolveinstancemethod 方法的返回值為bool,也就是這個方法返回yes 表示找到了動態方法的具體實現,否則就表示沒有在執行時找到真實的實現,程式就匯報錯。

經過了上面的處理,objective-c 的執行時只要發現你呼叫了@dynamic 標註的屬性的setter、getter 方法,就會自動到resolveinstancemethod 裡去尋找真實的實現。這也就是說你在main.m 中呼叫peson.height 的時候,實際上dynamicmethod 函式被呼叫了。實際上除了@dynamic 標註的屬性之外,如果你呼叫了型別中不存在的方法,也會被

category是objective-c中常用的語法特性,通過它可以很方便的為已有的類來新增函式。但是category不允許為已有的類新增新的屬性或者成員變數。    

一種常見的辦法是通過runtime.h中objc_getassociatedobject / objc_setassociatedobject來訪問和生成關聯物件。通過這種方法來模擬生成屬性。

//

nsobject+indiebandname.h

@inte***ce

nsobject (indiebandname)

@property (nonatomic, strong) nsstring *indiebandname;

@end

上面是標頭檔案宣告,下面的實現的.m檔案:

//

nsobject+indiebandname.m

#import

"nsobject+extension.h

"#import

static

const

void *indiebandnamekey = &indiebandnamekey;

@implementation

nsobject (indiebandname)

@dynamic indiebandname;

- (nsstring *)indiebandname

- (void)setindiebandname:(nsstring *)indiebandname

@end

這個和category無關,但是也是runtime.h的一種應用。dlintrospection,是 乙個nsobject category。它為nsobject提供了一系列擴充套件函式:  

@inte***ce

nsobject (dlintrospection)+ (nsarray *)classes;

+ (nsarray *)properties;

+ (nsarray *)instancevariables;

+ (nsarray *)classmethods;

+ (nsarray *)instancemethods;

+ (nsarray *)protocols;

+ (nsdictionary *)descriptionforprotocol:(protocol *)proto;

+ (nsstring *)parentclasshierarchy;

@end

通過這些函式,你可以在除錯時(通過po命令)或者執行時獲得物件的各種資訊。

id value = array[i];

array[i] = newobj;

id value = dictionary[@"key"];

dictionary[@"key"] = newobj;

上面幾行語句實際呼叫的方法分別對應如下:

nsarray : - (id)objectatindexedsubscript: (nsuinteger)index;

nsmutablearray : - (void)setobject: (id)obj atindexedsubscript: (nsuinteger)index;

nsdictionary : - (id)objectforkeyedsubscript: (id )key;

nsmutabledictionary : - (void)setobject: (id)anobject forkeyedsubscript: (id )akey;

在自己的類裡面實現這些方法就能用下標法了。

選自

這是乙個小「廢」貼

二,機器學習 特徵選擇 整合學習 1,k 鄰近演算法 2,線性回歸 3,決策樹 4,樸素貝葉斯演算法 5,邏輯回歸 6,聚類 sklearn中的使用 三,深度學習 tensorflow 四,資料庫 sql 五,資料結構與演演算法 傳送門 機器學習 pandas 資料的前處理 強力推薦 python之...

好點子分享 位址貼條

今天上午要寄ems,按照常規的做法,發件人,發件人位址,收件人,收件人位址,一項一項的填.填完之後,再三檢查,是否填錯了,這東西,填錯了,可沒有提示功能,說填錯了,叫重填,這些東西很容易填錯,而且又費時間.我就在想能不能簡化啦?現在資訊科技這麼發達,何不用於起來.能不能像google地圖一樣,先選好...

MIPS彙編小貼示

各欄位含義 op 指令基本操作,稱為操作碼。rs 第乙個源運算元暫存器。rt 第二個源運算元暫存器。rd 存放操作結果的目的運算元。shamt 位移量 funct 函式,這個字段選擇op操作的某個特定變體。有32個通用暫存器,0到 31 0 即 zero,該暫存器總是返回零,為0這個有用常數提供了乙...