Runtime初識(shí)

runtime的使用先導(dǎo)入runtime類(lèi)

#import <objc/runtime.h>

runtime 可以對(duì)類(lèi)操作
舉個(gè)例子
先創(chuàng)建一個(gè)Person類(lèi)
在.h中聲明方法

/*
1    + resolveInstanceMethod:(SEL)sel      // 為一個(gè)實(shí)例方法動(dòng)態(tài)添加實(shí)現(xiàn)
+ resolveClassMethod:(SEL)sel      //   為一個(gè)類(lèi)方法動(dòng)態(tài)添加實(shí)現(xiàn)
2     - (id)forwardingTargetForSelector:(SEL)aSelector
//為沒(méi)有實(shí)現(xiàn)的方法指定一個(gè)對(duì)象
3     - (void)forwardInvocation:(NSInvocation *)anInvocation
//子類(lèi)重載這個(gè)方法為消息指定其他對(duì)象
*/

在.m中使用

#import "Person.h"
#import <objc/runtime.h>

@implementation Person
/*
Ivar *class_copyIvarList(Class cls, unsigned int *outCount)      //獲取所有成員變量
const char *ivar_getName(Ivar v)            //獲取某個(gè)成員變量的名字
const char *ivar_getTypeEncoding(Ivar v)   //獲取某個(gè)成員變量的類(lèi)型編碼
Ivar class_getInstanceVariable(Class cls, const char *name)    //獲取某個(gè)類(lèi)中指定名稱(chēng)的成員變量
id object_getIvar(id obj, Ivar ivar)    //獲取某個(gè)對(duì)象中的某個(gè)成員變量的值
void object_setIvar(id obj, Ivar ivar, id value)    //設(shè)置某個(gè)對(duì)象的某個(gè)成員變量的值
TypeEncoding:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1
*/

- (NSString *)description
{
    // class:要獲取的某個(gè)類(lèi)掂林,outCount:通過(guò)這一個(gè)函數(shù)執(zhí)行之后會(huì)將成員變量的個(gè)數(shù)復(fù)制到此
    unsigned int outCount;
    Ivar *ivarList = class_copyIvarList([Person class], &outCount);
    for (NSInteger i = 0; i < outCount; i++) {
        // 每次獲取一個(gè)成員變量
        Ivar ivar = ivarList[i];
        // 打印成員變量的類(lèi)型編碼
        NSLog(@"name = %s", ivar_getName(ivar));
        NSLog(@"type = %s", ivar_getTypeEncoding(ivar));
        
    }
    return nil;
}

+ (Person *)personWithName:(NSString *)name gender:(NSString *)gender age:(NSNumber *)age weight:(NSInteger)weight
{
    Person *person = [Person new];
    unsigned int outCount;
    Ivar *ivarList = class_copyIvarList(self, &outCount);
    // obj:要設(shè)置的對(duì)象  ivar:要設(shè)置的對(duì)象的某一個(gè)屬性value:value
    object_setIvar(person, ivarList[0], name);
    object_setIvar(person, ivarList[1], gender);
    object_setIvar(person, ivarList[2], age);
    object_setIvar(person, ivarList[3], @(weight));
    
    return person;
}

- (void)getPersonMessage
{
    unsigned int outCount;
    Ivar *ivarList = class_copyIvarList([Person class], &outCount);
    for (NSInteger i = 0; i < outCount; i++) {
        NSLog(@"name = %s, value = %@", ivar_getName(ivarList[i]), object_getIvar(self, ivarList[i]));
    }
}

// 編碼
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    unsigned int outCount;
    Ivar *ivarList = class_copyIvarList([Person class], &outCount);
    for (NSInteger i = 0; i < outCount; i++) {
        const char *cName = ivar_getName(ivarList[i]);
        NSString *name = [NSString stringWithUTF8String:cName];
        
        [aCoder encodeObject:[self valueForKey:name] forKey:name];
    
    }
}

// 解碼
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        unsigned int outCount;
        Ivar *ivarList = class_copyIvarList([Person class], &outCount);
        for (NSInteger i = 0; i < outCount; i++) {
            const char *cName = ivar_getName(ivarList[i]);
            NSString *name = [NSString stringWithUTF8String:cName];
            [self setValue:[aDecoder decodeObjectForKey:name] forKey:name];
        }
    }
    return self;
}

/*
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSString *selString = NSStringFromSelector(sel);
    if ([selString isEqualToString:@"walkOnTheStreet:"]) {
        // 為一個(gè)沒(méi)有實(shí)現(xiàn)的方法動(dòng)態(tài)添加實(shí)現(xiàn)
 
         cls:類(lèi)
         name:沒(méi)有實(shí)現(xiàn)的方法名
         IMP:要添加的實(shí)現(xiàn)
         types:動(dòng)態(tài)添加的實(shí)現(xiàn)的類(lèi)型編碼
 
        class_addMethod(self, @selector(walkOnTheStreet:), (IMP)walkFunc, "V@:@");
    }
    return [super resolveInstanceMethod:sel];
}
*/
void walkFunc(id self, SEL sel, NSString *str){
    NSLog(@"Person -- %s, %@", __func__, str);
}

// 切換消息轉(zhuǎn)換對(duì)象 方式一

/*
- (id)forwardingTargetForSelector:(SEL)aSelector
{
    NSString *selString = NSStringFromSelector(aSelector);
    if ([selString isEqualToString:@"walkOnTheStreet:"]) {
        self.dog = [Dog new];
        return self.dog;
        
    }
    else {
        return [super forwardingTargetForSelector:aSelector];
    }
}
*/

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    if ([Dog instancesRespondToSelector:anInvocation.selector]) {
        self.dog = [Dog new];
        [anInvocation invokeWithTarget:self.dog];
    }
}

// 給方法制定一個(gè)有效的簽名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *methodSignature = [super methodSignatureForSelector:aSelector];
    if (!methodSignature) {
        methodSignature = [Dog instanceMethodSignatureForSelector:aSelector];
    }
    return methodSignature;
}

runtime在類(lèi)目中的使用

/* 
 void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)     //為某個(gè)類(lèi)關(guān)聯(lián)某個(gè)對(duì)象
 id objc_getAssociatedObject(id object, const void *key)
 //獲取到某個(gè)類(lèi)的某個(gè)關(guān)聯(lián)對(duì)象
 void objc_removeAssociatedObjects(id object) //移除已經(jīng)關(guān)聯(lián)的對(duì)象
*/

可以為某個(gè)類(lèi)關(guān)聯(lián)對(duì)象

- (void)setName:(NSString *)name {
    // objc:要關(guān)聯(lián)的對(duì)象 key:成員變量對(duì)應(yīng)的key值宪躯,@selector(屬性名)value:value
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    return objc_getAssociatedObject(self, @selector(name));
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子空扎,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異佃延,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)夷磕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)履肃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人坐桩,你說(shuō)我怎么就攤上這事尺棋。” “怎么了撕攒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵陡鹃,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抖坪,道長(zhǎng)萍鲸,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任擦俐,我火速辦了婚禮脊阴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚯瞧。我一直安慰自己嘿期,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布埋合。 她就那樣靜靜地躺著备徐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪甚颂。 梳的紋絲不亂的頭發(fā)上蜜猾,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音振诬,去河邊找鬼蹭睡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赶么,可吹牛的內(nèi)容都是我干的肩豁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辫呻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼清钥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起放闺,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤循捺,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后雄人,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體从橘,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年础钠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恰力。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旗吁,死狀恐怖踩萎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情很钓,我是刑警寧澤香府,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布董栽,位于F島的核電站,受9級(jí)特大地震影響企孩,放射性物質(zhì)發(fā)生泄漏锭碳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一勿璃、第九天 我趴在偏房一處隱蔽的房頂上張望擒抛。 院中可真熱鬧,春花似錦补疑、人聲如沸歧沪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诊胞。三九已至,卻和暖如春锹杈,著一層夾襖步出監(jiān)牢的瞬間厢钧,已是汗流浹背疙咸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工铜涉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沉填。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓市框,卻偏偏與公主長(zhǎng)得像霞扬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枫振,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 這里就不說(shuō)runtime有多牛逼了喻圃。直接進(jìn)入正題。 首先Objective-C是面向?qū)ο蟮姆嗦耍魏晤?lèi)的定義都是對(duì)象斧拍。...
    進(jìn)擊的小杰閱讀 860評(píng)論 3 7
  • Runtime 運(yùn)行時(shí),是一套底層的 C 語(yǔ)言 API杖小,其為 iOS 內(nèi)部的核心之一肆汹,我們平時(shí)編寫(xiě)的 OC 代碼,...
    剎那_芳華閱讀 302評(píng)論 1 0
  • 我們隨便寫(xiě)一個(gè)小程序予权,代碼如下: person類(lèi)頭文件如下昂勉, #import@interfacePerson : ...
    program袁閱讀 264評(píng)論 0 1
  • Objective-C Runtime Describes the macOS Objective-C runti...
    Jackey_Zhou閱讀 130評(píng)論 0 0
  • 蘇州客 S醫(yī)院腫瘤科的大單間,位于護(hù)士站對(duì)面扫腺,默認(rèn)的重癥室岗照。此時(shí),幾個(gè)家屬默默肅立。 床...
    蘇州客閱讀 248評(píng)論 2 2