oc 函數(shù)傳遞機(jī)制,崩潰處理

/**

總結(jié):

在一個(gè)函數(shù)找不到時(shí),OC提供了三種方式去補(bǔ)救:

1、調(diào)用resolveInstanceMethod給個(gè)機(jī)會(huì)讓類添加動(dòng)態(tài)添加方法去實(shí)現(xiàn)這個(gè)函數(shù)

2、調(diào)用forwardingTargetForSelector讓別的對(duì)象去執(zhí)行這個(gè)函數(shù)

3、調(diào)用forwardInvocation(函數(shù)執(zhí)行器)靈活的將目標(biāo)函數(shù)以其他形式執(zhí)行。用methodSignatureForSelector先偷換方法的簽名

如果都不中,調(diào)用doesNotRecognizeSelector拋出異常。

*/

#import"ViewController.h"

#import"Person.h"

#import"NSObject+Runtime.h"

@interfaceViewController()

@property(nonatomic,strong)Person*person;

@end

@implementationViewController

- (void)viewDidLoad {

[superviewDidLoad];

_person= [Personalloc];

[_personperformSelector:@selector(shaleba)];

}

@end

#import"Person.h"

#import

@implementationPerson


#pragma mark - crush最先調(diào)用,可以在這里用運(yùn)行時(shí)交換方法

+(BOOL)resolveInstanceMethod:(SEL)sel{

if(sel ==@selector(shaleba)) {

class_addMethod([selfclass],sel,class_getMethodImplementation(self,@selector(startEngine)),"@@:");

returnNO;

}

return[superresolveInstanceMethod:sel];

}

//上面??替換的方法

- (void)startEngine {

NSLog(@"我執(zhí)行后就不會(huì)再崩潰了");

}

#pragma mark - crush第二調(diào)用,可以在這里直接指定一個(gè)對(duì)象去調(diào)用

-(id)forwardingTargetForSelector:(SEL)aSelector{

self.stu= [studentnew];

returnself.stu;

}

#pragma mark - crush第3接鍋俠之一這個(gè)是和下面方法一起使用的,可以在這里直接指定一個(gè)對(duì)象去調(diào)用

-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{

self.stu= [studentnew];

NSMethodSignature*signature =nil;

//如果自己變身的類有改方法,則偷取出方法的簽名

if([self.stumethodSignatureForSelector:aSelector]) {

//OC所有的底層方法至少有兩個(gè)參數(shù)第一個(gè)參數(shù)方法的對(duì)象self第二個(gè)參數(shù):方法的自身我們?nèi)斯な謱懙姆椒▍?shù)是從第三個(gè)開始

signature = [self.stumethodSignatureForSelector:aSelector];

}

else{

signature = [supermethodSignatureForSelector:aSelector];

}

returnsignature;

}

#pragma mark - crush第3接鍋俠之一這個(gè)是和下面方法一起使用的,可以在這里直接指定一個(gè)對(duì)象去調(diào)用

//2.再檢查方法的實(shí)現(xiàn)(調(diào)用方法)

- (void)forwardInvocation:(NSInvocation*)invocation{

//設(shè)置方法的執(zhí)行者為自己copy的哪一個(gè)類,必須設(shè)置不然不會(huì)調(diào)用此方法

[invocationsetTarget:self.stu];

//動(dòng)態(tài)攔截參數(shù),修改參數(shù)

if([self.stuisKindOfClass:NSClassFromString(@"Teacher")]) {

//argument:參數(shù)的地址index:參數(shù)的下標(biāo)

NSString*s =@"呵呵,被改了";

[invocationsetArgument:&satIndex:2];

}

//讓自己的替身類去調(diào)用方法

[invocationinvoke];

}

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容