摘 要:RunTime是系統(tǒng)運(yùn)行時(shí)的機(jī)制,其中最主要的是消息機(jī)制。本文主要對(duì)Runtime的消息機(jī)制進(jìn)行研究并分析了其運(yùn)行過(guò)程,最后結(jié)合實(shí)例闡述了該機(jī)制的使用方法。
關(guān)鍵詞:Runtime 運(yùn)行時(shí) 動(dòng)態(tài)調(diào)用 消息機(jī)制
一、引言
目前,Obj-C被廣泛應(yīng)用于蘋(píng)果的設(shè)備中,包括IOS系統(tǒng),Mac OS系統(tǒng)等。雖然目前已有Swift出現(xiàn),但是由于Obj-C有更好的底層屬性值得研究,對(duì)于熟悉和深入研究蘋(píng)果系統(tǒng)有非常高的研究?jī)r(jià)值。其中Runtime機(jī)制就是Obj-C的一大特色,能在運(yùn)行期處理的機(jī)制。本文對(duì)消息機(jī)制進(jìn)行了研究分析,并闡述了其實(shí)際運(yùn)用。
二、Runtime中消息機(jī)制的研究
#include
void printHi(){printf(“Say Hi!\n”);}
void printBye(){printf(“Say Bye?。躰”);}
void doTheTing(int type){
void (*func)();
if(type==0){
func = printHi;
}else{func = printBye;}
func();
return 0;}
在上述例子中,只有一個(gè)函數(shù)調(diào)用指令,待調(diào)用的的函數(shù)地址無(wú)法硬編碼在指令中,而是要在運(yùn)行期才能知道,這是一個(gè)動(dòng)態(tài)綁定。在Obj-C中,如果要向一個(gè)對(duì)象傳遞一個(gè)消息,那么就會(huì)使用這種“動(dòng)態(tài)綁定”機(jī)制來(lái)決定所需要調(diào)用的方法。
在Obj-C中,給對(duì)象發(fā)送消息可以這樣寫(xiě):
id value = [Object messageName:parameter];
這個(gè)實(shí)例中,Object是“接受者”(receiver),messageName叫做“選擇子”(selector)。兩者結(jié)合起來(lái)就是“消息”。編譯器在讀取這條消息后,會(huì)將其轉(zhuǎn)變?yōu)橐粭l普通的C語(yǔ)言函數(shù)調(diào)用。這個(gè)函數(shù)叫做objc_msgSend,其中“原型”如下:
id value = obj_msgSend(Object ,@selector(messageName:),parameter);
這就是運(yùn)行期中Obj-C的消息機(jī)制,Obj-C中的類(lèi)都繼承自NSObject。
@interface NSObject
Class isa OBJC_ISA_AVAILABILITY;
}
其中存在一個(gè)指向Class的isa指針,那么再來(lái)看下Class這個(gè)類(lèi)。
typedef struct objc_class *Class;
struct objc_class {
Class isa;
Class super_class ;
const char *name ;
long version ;
long info;
long instance_size ;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists ;
struct objc_cache *cache;
struct objc_protocol_list *protocols; }
在這個(gè)類(lèi)中存在很多屬性,一般一個(gè)Obj對(duì)象中的isa會(huì)指向普通的Class,這個(gè)Class中存儲(chǔ)普通成員變量和對(duì) 象方法(“-”開(kāi)頭的方法),普通Class中的isa指針指向靜態(tài)Class,靜態(tài)Class中存儲(chǔ)static類(lèi)型成員變量和類(lèi)方法(“+”開(kāi)頭的方法)。Class super_class:指向父類(lèi),如果這個(gè)類(lèi)是根類(lèi),則為NULL。
三、Runtime機(jī)制的實(shí)際運(yùn)用
在IOS或者M(jìn)ac OS的編程中,經(jīng)常會(huì)遇到歸檔與解檔,常規(guī)的歸檔與解檔要對(duì)數(shù)據(jù)進(jìn)行序列化和反序列化,并且代碼重用率很高。現(xiàn)在,通過(guò)Runtime的機(jī)制來(lái)對(duì)其進(jìn)行操作。
首先是構(gòu)建Cat的類(lèi)文件,如下所示。
@protocol CatDelegate
- (void)catEat;
@end
@interface Cat : NSObject
#pragma mark - 屬性
@property (nonatomic , assign) id
@property (nonatomic , copy) NSString *name;
@property (nonatomic , copy) NSString *sex;
@property (nonatomic , assign) int age;
#pragma mark - 方法
- (void)eat;
- (void)sleep;
@end
在此方法類(lèi)中定義了name,sex,age等屬性,通過(guò)之前的敘述,可以明白這些屬性已經(jīng)在Class中訪(fǎng)問(wèn)到,那么,我們通過(guò)改寫(xiě).m文件來(lái)實(shí)現(xiàn)該類(lèi)的歸檔與解檔。如下所示
@interface Cat()
@end
@implementation Cat
-(void)encodeWithCoder:(NSCoder *)aCoder{
unsigned int count;
objc_property_t *properties = class_copyPropertyList([self class], count);
for (int i =0; i objc_property_t property = properties[i]; const char *name = property_getName(property); NSString *propertyName = [NSString stringWithUTF8String:name]; NSString *propertyValue = [self valueForKey:propertyName]; [aCoder encodeObject:propertyValue forKey:propertyName]; }free(properties);} 接下來(lái),通過(guò)實(shí)現(xiàn)方法來(lái)看下具體的結(jié)果。如下代碼和圖1所示。 -(void)test{ Cat *cat = [[Cat alloc] init]; cat.name = @”貓1\"; cat.age = 3; cat.sex = @\"公\"; NSString *path = [NSString stringWithFormat:@\"%@/archive\",NSHomeDirectory()]; [NSKeyedArchiver archiveRootObject:cat toFile:path]; Cat *unarchiverCat = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@\"unarchiverCat== %@ %@\",path , unarchiverCat);} 通過(guò)這種方法,歸檔和解檔的步驟變得非常簡(jiǎn)單,也使程序的調(diào)度變得非常實(shí)用,高效。 四、結(jié)語(yǔ) 通過(guò)介紹Runtime的機(jī)制的使用方法,使得開(kāi)發(fā)者可以懂得Obj-C真正的運(yùn)行過(guò)程,靈活運(yùn)用Runtime機(jī)制可以更好的操控程序,懂得如何在運(yùn)行中控制程序,以深入理解Objective-C的Runtime數(shù)據(jù)結(jié)構(gòu)、消息轉(zhuǎn)發(fā)機(jī)制有助于更容易地閱讀和學(xué)習(xí)開(kāi)源項(xiàng)目。 參考文獻(xiàn): [1] Matt Galloway. Effective Object-C 2.0:編寫(xiě)高質(zhì)量ios與OS X代碼的52個(gè)有效方法;機(jī)械工業(yè)出版社,2015,08. [2] 劉樂(lè),李敬兆. IOS內(nèi)存開(kāi)發(fā)管理機(jī)制的研究[J]; 安徽理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院,2013,03. [3] 王文東,竹林,建人. 匯編語(yǔ)言與C語(yǔ)言的混合程序設(shè)計(jì)技術(shù)[D]. 延安大學(xué),2006,08. [4] 鐘冠賢. Object-C編程之道:IOS設(shè)計(jì)模式;北京:人民郵電出版社,2011,01. [5] 唐巧,Blogger. IOS開(kāi)發(fā)進(jìn)階[M].北京:電子工業(yè)出版社,2015,01.