Runtime常見作用舉例

Runtime主要有如下常見的作用:

  • 動態(tài)的添加對象的成員變量和方法,修改屬性值和方法
  • 動態(tài)交換兩個方法的實現
  • 實現分類也可以添加屬性
  • 攔截并替換方法

實現代碼

通過創(chuàng)建Car類來實現

  • Car.h
#import <Foundation/Foundation.h>
@interface Car : NSObject
@property (nonatomic, copy) NSString *name;
- (void)run;
- (void)stop;
@end
  • Car.m
#import "Car.h"
@implementation Car
- (void)run {
    NSLog(@"%@跑", self.name);
}
- (void)stop {
    NSLog(@"%@停車", self.name);
}
@end
1.動態(tài)變量控制
- (void)changeVariable {
    Car *myLancrusier = [[Car alloc] init];
    myLancrusier.name = @"陸地巡洋艦";
    NSLog(@"我的車:%@", myLancrusier.name);
    
    unsigned int count;
    Ivar *ivars = class_copyIvarList([myLancrusier class], &count);
    for (int i = 0; i < count; i ++) {
        Ivar ivar = ivars[i];
        const  char *varName = ivar_getName(ivar);//獲取成員變量名,-->C類型的字符串
        NSString *ivarNameString = [NSString stringWithCString:varName encoding:NSUTF8StringEncoding];
        if ([ivarNameString isEqualToString:@"_name"]) {
            object_setIvar(myLancrusier, ivar, @"路上蒼龍");
            break;
        }
    }
    free(ivars);//使用完畢,必須釋放
    NSLog(@"我的車:%@", myLancrusier.name);
}

注意:下面兩個兩個方法返回的指針使用完畢必須free()
class_copyIvarList()返回一個指向類的成員變量數組的指針
class_copyPropertyList()返回一個指向類的屬性數組的指針
輸出結果:

2016-09-10 21:04:09.392 Runtime[3875:764447] 我的車:陸地巡洋艦
2016-09-10 21:04:09.392 Runtime[3875:764447] 我的車:路上蒼龍
2.動態(tài)添加方法
void happyNewCar (id self, SEL _cmd) {
    NSLog(@"我新買了一輛豐田陸地巡洋艦最新款");
}

- (void)addAMethod {
    Car *myCar = [Car new];
    myCar.name = @"陸地巡洋艦新款";
    
    class_addMethod([myCar class], @selector(newMyCar), (IMP)happyNewCar, "v@:");
    [myCar performSelector:@selector(newMyCar)];
}

備注:
為了支持消息的轉發(fā)和動態(tài)調用,Objective-C Method 的 Type 信息也被以“返回值 Type + 參數 Types”的形式組合編碼,還要考慮到 self 和 _cmd 這兩個隱含參數(此處引用自參考2):

- (void)foo; => "v@:"
- (int)barWithBaz:(double)baz; => "iv@:d"

1.happyNewCar()selector:newMyCar的IMP。這個函數至少要有兩個參數:self, _cmd
2.v@:中各個字符代表不同的含義。具體參考Objective-C Runtime Programming Guide>Type Encodings。舉例如下:

Code Meaning
v A void
@ An object(whether statically typed or typed id)
: A method selector(SEL)
  1. 為支持消息的轉發(fā)和動態(tài)調用,Objective-C Method 的 Type 信息也被以 “返回值 Type + 參數 Types” 的形式組合編碼,還需要考慮到 self 和 _cmd 這兩個隱含參數:

輸出結果:

2016-09-10 21:04:09.392 Runtime[3875:764447] 我新買了一輛豐田陸地巡洋艦最新款
3.動態(tài)為category添加屬性
  • Car+Category.h
#import "Car.h"
@interface Car (Category)
@property(nonatomic, copy) NSString *color;
@end
  • Car+Category.m
#import "Car+Category.h"
#import <objc/runtime.h>
@implementation Car (Category)
const char c_color;
- (void)setColor:(NSString *)color {
    objc_setAssociatedObject(self, &c_color, color, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)color {
    return objc_getAssociatedObject(self, &c_color);
}
@end

調用

- (void)addExtentProperty {
    Car *myCar = [Car new];
    myCar.color = @"red";
    NSLog(@"myCar添加的顏色為%@", myCar.color);
}

輸出:

2016-09-10 21:04:09.392 Runtime[3875:764447] myCar添加的顏色為red
4.動態(tài)交換方法
- (void)exchangeMethod {
    Car *myCar = [Car new];
    myCar.name = @"陸上蒼龍";
    [myCar run];
    [myCar stop];
    
    NSLog(@"--------交換方法------------");
    Method m1 = class_getInstanceMethod([myCar class], @selector(run));
    Method m2 = class_getInstanceMethod([myCar class], @selector(stop));
    method_exchangeImplementations(m1, m2);
    [myCar run];
    [myCar stop];
}

輸出:

2016-09-10 21:04:09.393 Runtime[3875:764447] 陸上蒼龍跑
2016-09-10 21:04:09.393 Runtime[3875:764447] 陸上蒼龍停車
2016-09-10 21:04:09.393 Runtime[3875:764447] --------交換方法------------
2016-09-10 21:04:09.393 Runtime[3875:764447] 陸上蒼龍停車
2016-09-10 21:04:09.394 Runtime[3875:764447] 陸上蒼龍跑
5.攔截并替換方法

在程序中,由于某些原因,我們需要改變某個方法的實現,但是又不能去動它的源代碼(如一些開源庫有問題的時候),就需要runtime了。

demo代碼:

demo

參考

  1. RunTime
  2. 重識 Objective-C Runtime - 看透 Type 與 Value
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,812評論 7 64
  • 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的轉載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,886評論 33 466
  • 轉至元數據結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 2,051評論 0 9
  • 文/有料帝 問天下情為何物,只教人生死相許!多情本是無情物,癡情原非無情因!風陵渡口初相遇,一見楊過誤終身!只恨我...
    有料帝閱讀 31,327評論 2 16
  • 如何將創(chuàng)建的文檔放到指定目錄image.png
    bo_bo_bo_la閱讀 275評論 0 2

友情鏈接更多精彩內容