ios 動態執行的代碼

來源:互聯網
上載者:User

標籤:

objc中可以通過動態啟動並執行方法調用第三方庫的函數

通過可以用下面的方法判斷工程是否引入了第三方的庫,如果引入,則可以通過NtSdkIMP擷取到對應方法的函數指標去執行代碼。如果沒有引入,則不執行。

通過擷取方法的imp指標,可以運行對應的函數,如果imp為空白,說明不包含所需要的庫和符號。

@interface ViewController ()@end@implementation ViewController- (int)printOneNumber:(int)number {    NSLog(@"print number %d", number);    return number + 1;}+ (NSString *)numberAddOne:(NSString *)num {    NSInteger n = [num integerValue];    n++;    NSString *ret = [NSString stringWithFormat:@"%ld", n];    NSLog(@"%@", ret);    return ret;}

如上面 ViewController 包含有

printOneNumber

numberAddOne這兩個方法,

通常可以通過 int ret = [self printOneNumber:1] 調用來執行對應的函數方法也可以通過下面的imp來調用,過程比較複雜,但可以在沒有聲明或者引用對應標頭檔就可以執行對應代碼

- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.        NSString *methodName = @"printOneNumber:";    IMP imp = [NtSdkIMP getInstance:self method:methodName];    int (*func)(id, SEL, ...) = (void *)imp;    if (func) {        SEL selector = NSSelectorFromString(methodName);        int ret = func(self, selector, 4);        NSLog(@"%d", ret);    }        imp = [NtSdkIMP getClass:@"ViewController" method:@"numberAddOne:"];    id (*func2)(id, SEL, ...) = (void *)imp;    if (func2) {        SEL selector = NSSelectorFromString(@"numberAddOne:");        Class classA = NSClassFromString(@"ViewController");        id s = func2(classA, selector, @"4");        NSLog(@"%@",s);            }}

如果返回的是nsobject對像,則需要用

id (*func2)(id, SEL, ...)

設定imp的格式

如果返回的是基礎資料類型(非執行個體對象),則需要

int (*func)(id, SEL, ...)

設定imp的格式

對應的NtSdkIMP代碼如下:

#import <Foundation/Foundation.h>@interface NtSdkIMP : NSObject/** *  擷取類方法的函數指標 * *  @param className  對象 *  @param methodName 方法 * *  @return 函數指標 */+ (IMP)getClass:(NSString *)className method:(NSString *)methodName;/** *  擷取對象方法的函數指標 * *  @param instance   對象 *  @param methodName 方法 * *  @return 函數指標 */+ (IMP)getInstance:(id)instance method:(NSString *)methodName;/** *  列印出要調用的類方法 * *  @param className  類名 *  @param methodName 方法名 *  @param arguments  參數列表 */+ (void)LogClass:(NSString *)className runMethod:(NSString *)methodName withArgs:(NSArray *)arguments;/** *  列印出要調用的對象方法 * *  @param className  類名 *  @param methodName 方法名 *  @param arguments  參數列表 */+ (void)LogInstance:(NSString *)instanceName runMethod:(NSString *)methodName withArgs:(NSArray *)arguments;@end

 

#import "NtSdkIMP.h"#import "NTLog.h"@implementation NtSdkIMP+ (IMP)getClass:(NSString *)className method:(NSString *)methodName {        Class classA = NSClassFromString(className);        //存在該類    if (classA)    {        NTLog(@"Class %@ Exist", className);        SEL selector = NSSelectorFromString(methodName);        //存在對應的方法        if ([classA respondsToSelector:selector])        {            NTLog(@"Method %@ Exist", methodName);            IMP imp = [classA methodForSelector:selector];            return imp;        }        //不存在對應的方法        else {            NTLog(@"Method NOT %@ Exist", methodName);            return NULL;        }    }    //存在該類    else {        NTLog(@"Class %@ NOT exist", className);        return NULL;    }}+ (IMP)getInstance:(id)instance method:(NSString *)methodName {        //對象存在    if (instance) {        NTLog(@"Instance %@ Exist", instance);    }    //對象不存在    else {        NTLog(@"Instance %@ NOT Exist", instance);        return NULL;    }        SEL selector = NSSelectorFromString(methodName);    //存在對應方法    if ([instance respondsToSelector:selector])    {        NTLog(@"Method %@ Exist", methodName);        IMP imp = [instance methodForSelector:selector];        return imp;    }    //不存在對應方法    else {        NTLog(@"Method %@ NOT Exist", methodName);        return NULL;    }}+ (void)LogClass:(NSString *)className runMethod:(NSString *)methodName withArgs:(NSArray *)arguments {    NTLog(@"className:%@",className);    NTLog(@"method:%@", methodName);    for (NSObject *object in arguments) {        NTLog(@"%@ %@", object.class, object);    }    //方法名隊列。如果沒有參數,不包括冒號,如果有多個參數,有冒號相隔,且最後一個方法名為@""    NSMutableArray *arrMethod = [NSMutableArray arrayWithArray:[methodName componentsSeparatedByString:@":"]];        //方法名不存在    if (arrMethod.count < 1) {        NTLog(@"methodname is nil");        return;    }    NSMutableString *stringMethods = [[NSMutableString alloc] init];    NSUInteger i = 0;    //不帶參數    if (arrMethod.count == 1) {        [stringMethods appendString:[arrMethod firstObject]];    }    //多個參數    else {        for (NSString *method in arrMethod) {            if ([method isEqualToString:@""]) {                break;//最後一個是@"",需要去掉            }            [stringMethods appendString:method];            [stringMethods appendString:@":"];            //參數不為空白對象            if ([arguments objectAtIndex:i]) {                [stringMethods appendString:[[arguments objectAtIndex:i] description]];            }            //參數是Null 物件            else {                [stringMethods appendString:@"nil"];            }            //加個空格            if ([arrMethod indexOfObject:method] != arrMethod.count-2) {                [stringMethods appendString:@" "];            }        }    }    //列印出要調的類方法    NTLog("\nRun Class Method: [%@ %@]", className, stringMethods);}#pragma mark TODO:+ (void)LogInstance:(id)instance runMethod:(NSString *)methodName withArgs:(NSArray *)arguments {    }@end

 

ios 動態執行的代碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.