代码如下:+(void)load{staticdispatch_once_tonceToken;dispatch_once(&onceToken,^{Classclass=[NSURLConnectionclass];SELselector=@selector(initWithRequest:delegate:);SELswizzledSelector=@selector(test_initWithRequest:delegate:);MethodoriginalinitWithRequest=class_getInstanceMethod(class,selector);NSURLConnection*(^swizzleBlock)(NSURLConnection*,SEL,NSURLRequest*,id)=^(NSURLConnection*slf,SELswizzledSelector,NSURLRequest*request,iddelegate){return((NSURLConnection*(*)(NSURLConnection*,SEL,NSURLRequest*,id))objc_msgSend)(slf,swizzledSelector,request,delegate);};IMPimplementation=imp_implementationWithBlock(swizzleBlock);class_addMethod(class,swizzledSelector,implementation,method_getTypeEncoding(originalinitWithRequest));MethodnewConnectionWithRequestClassMethod=class_getInstanceMethod(class,swizzledSelector);method_exchangeImplementations(originalinitWithRequest,newConnectionWithRequestClassMethod);});}我看了半天没发现什么问题,为什么这样一交换之后运行就会崩溃。在return时候打断点,信息如下:(lldb)poslf{request:(null)}(lldb)poswizzledSelector{URL:http://httpstat.us/200}(lldb)porequest(lldb)podelegatenil崩溃信息如下:2017-12-1915:09:25.923HookNetwork2[4030:501650]***NSForwarding:warning:selector(0x60000000e020)formessage'Xˆü'doesnotmatchselectorknowntoObjectiveCruntime(0x608000004340)--abort2017-12-1915:09:25.924HookNetwork2[4030:501650](null):unrecognizedselectorsenttoinstance0x60000000dea02017-12-1915:09:25.928HookNetwork2[4030:501650]***Terminatingappduetouncaughtexception'NSInvalidArgumentException',reason:'(null):unrecognizedselectorsenttoinstance0x60000000dea0'***Firstthrowcallstack:(0CoreFoundation0x000000010926fb0b__exceptionPreprocess+1711libobjc.A.dylib0x0000000108cd4141objc_exception_throw+482CoreFoundation0x00000001092df134-[NSObject(NSObject)doesNotRecognizeSelector:]+1323CoreFoundation0x00000001091f6840___forwarding___+10244CoreFoundation0x00000001091f63b8_CF_forwarding_prep_0+1205HookNetwork20x00000001086fc379__20+[RAObservererload]_block_invoke_2+1536HookNetwork20x00000001086fd6a3-[ViewControllerconnectTest:]+17317UIKit0x0000000109694d82-[UIApplicationsendAction:to:from:forEvent:]+838UIKit0x00000001098195ac-[UIControlsendAction:to:forEvent:]+679UIKit0x00000001098198c7-[UIControl_sendActionsForEvents:withEvent:]+45010UIKit0x0000000109818802-[UIControltouchesEnded:withEvent:]+61811UIKit0x00000001097027ea-[UIWindow_sendTouchesForEvent:]+270712UIKit0x0000000109703f00-[UIWindowsendEvent:]+411413UIKit0x00000001096b0a84-[UIApplicationsendEvent:]+35214UIKit0x0000000109e945d4__dispatchPreprocessedEventFromEventQueue+292615UIKit0x0000000109e8c532__handleEventQueue+112216CoreFoundation0x0000000109215c01__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+1717CoreFoundation0x00000001091fb0cf__CFRunLoopDoSources0+52718CoreFoundation0x00000001091fa5ff__CFRunLoopRun+91119CoreFoundation0x00000001091fa016CFRunLoopRunSpecific+40620GraphicsServices0x000000010d044a24GSEventRunModal+6221UIKit0x0000000109693134UIApplicationMain+15922HookNetwork20x00000001086ff2bfmain+11123libdyld.dylib0x000000010c0d965dstart+124???0x00000000000000010x0+1)libc++abi.dylib:terminatingwithuncaughtexceptionoftypeNSException前面的代码哪里有问题,为什么断点信息是这样的?这里有一个crashdemo,可以下载下来看一看。
2 回答
慕容森
TA贡献1853条经验 获得超18个赞
建议阅读一下imp_implementationWithBlock的文档。ParametersblockTheblockthatimplementsthismethod.Thesignatureofblockshouldbemethod_return_type^(idself,self,method_args…).Theselectorofthemethodisnotavailabletoblock.blockiscopiedwithBlock_copy().你的代码里面的block的类型里面是需要了一个seletor,打断点的得知,此时swizzleselector的值是一个NSURLRequest,明显不是我们想要的selector,所以objc_msgSend就失败了。查阅文档可知,block的签名应该是method_return_type^(idself,self,method_args…).是不需要SEL的,所以将上述的代码改为:idswizzleBlock=^(NSURLConnection*slf,NSURLRequest*request,iddelegate){return((NSURLConnection*(*)(NSURLConnection*,SEL,NSURLRequest*,id))objc_msgSend)(slf,swizzledSelector,request,delegate);};运行可以成功,点击按钮也OK了。
慕妹3242003
TA贡献1824条经验 获得超6个赞
那个RAObserverer是什么东西?代码里没有,奔溃调用栈里看起来跟上面代码没关系。需要知道这两句是干了什么,从调用栈看是RAObserverer没有load方法的实现5HookNetwork20x00000001086fc379__20+[RAObservererload]_block_invoke_2+1536HookNetwork20x00000001086fd6a3-[ViewControllerconnectTest:]+1731关键:imp_implementationWithBlock这个block的参数里是没有SEL的
添加回答
举报
0/150
提交
取消