Objective-c IOS arm64 swizzling method cannot call the original method

I use the standard swizzling method on ARMv7 iOS devices and it works great for me.

But when I compile my code for arm64 - it cannot call the original method from the new method

The main purpose of my swizzling is to use a parameter from the internal method of my application in another method.

I have an original method -(void)insertdata:(id)text , and I want to change it to -(void)patchedCall:(id)text and call the original method in a new method.

the code:

 static IMP sOriginalImp = NULL; @interface TextOverrides: NSObject +(void)load; -(void)patchedinsert:(id)text; @end @implementation TextOverrides +(void)load { //Get Implementation of original method Class originalClass = NSClassFromString(@"DataViewController"); Method originalMeth = class_getInstanceMethod(originalClass, @selector(insertdata:)); //Save original method implementation sOriginalImp = method_getImplementation(originalMeth); // Get implementation of replacement method Method replacementMeth = class_getInstanceMethod(NSClassFromString(@"TextOverrides"), @selector(patchedCall:)); //Replace methods method_exchangeImplementations(originalMeth, replacementMeth); } -(void)patchedCall:(id)text { @synchronized(self){ //Call of original method that we save sOriginalImp(self, @selector(insertdata:), text); //Make our code for argument "text" printf("Here is data%s\n", [text UTF8String]); } } @end 

Code crash when calling source method in arm64 architecture:

 //Call of original method that we save sOriginalImp(self, @selector(insertdata:), text); 

How can I improve my code to work on both armv7 and arm64?

+5
source share
2 answers

With a discussion https://github.com/square/PonyDebugger/issues/84 I think the essence is https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit/ConvertingYourAppto64- Bit.html # // apple_ref / doc / uid / TP40013501-CH3-SW22 and the fact that IMP is defined as a variational function, and you call it with fixed arguments. In my case, casting a function pointer to a real signature fixed the crash. I believe in your business, something like

 //Call of original method that we save ((void(*)(id, SEL, id))ssOriginalImp)(self, @selector(insertdata:), text); 

may fix the failure.

+2
source

I do not think that the loading order of all classes is specified somewhere. Thus, the TextOverrides class can be loaded to the DataViewController on arm64, but not on armv7. See https://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html

To make it stable, you should use only the swizzle methods in the load + category method. For instance:

 @interface DataViewController (TextOverrides) +(void)load; -(void)patchedinsert:(id)text; @end @implementation DataViewController (TextOverrides) +(void)load { // swizzle here } ... 
0
source

Source: https://habr.com/ru/post/1208726/


All Articles