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來訪問和生成關聯物件。通過這種方法來模擬生成屬性。
//上面是標頭檔案宣告,下面的實現的.m檔案:nsobject+indiebandname.h
@inte***ce
nsobject (indiebandname)
@property (nonatomic, strong) nsstring *indiebandname;
@end
//這個和category無關,但是也是runtime.h的一種應用。dlintrospection,是 乙個nsobject category。它為nsobject提供了一系列擴充套件函式: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
@inte***ce通過這些函式,你可以在除錯時(通過po命令)或者執行時獲得物件的各種資訊。nsobject (dlintrospection)+ (nsarray *)classes;
+ (nsarray *)properties;
+ (nsarray *)instancevariables;
+ (nsarray *)classmethods;
+ (nsarray *)instancemethods;
+ (nsarray *)protocols;
+ (nsdictionary *)descriptionforprotocol:(protocol *)proto;
+ (nsstring *)parentclasshierarchy;
@end
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這個有用常數提供了乙...