Are method swizzling and isa swizzling the same thing? If not, then what is isa swizzling?
Method swizzling is the process of replacing the implementation of a function at runtime. Swift, as a static, strongly typed language, did not previously have any built-in mechanism that would allow to dynamically change the implementation of a function.
iOS Swift Tips. Swizzling (other languages call this “monkey patching”) is the process of replacing a certain functionality or adding custom code before the original code is called. For example, you could swizzle UIViewController.
Method swizzling exchanges the implementation of two methods of a class at runtime. This will affect every instance, which was or will be created, of the modified class.
Example: Let's assume you have written a category for NSString:
@interface NSString (Swizzling)
@end
@implementation NSString (Swizzling)
- (NSString *)swizzled_uppercaseString {
//when the method is swizzled, the original method will be called
//with swizzled_uppercaseString (so this will not create a stack overflow).
NSString *result = [self swizzled_uppercaseString];
// our custom code
result = [result stringByAppendingString:@" (swizzled)"];
return result;
}
@end
You can then exchange the implementation of the uppercaseString
-method with the swizzled_uppercaseString
-method, so the implementation of the swizzled_uppercaseString
method is executed, when uppercaseString
is called. (And the original implementation of uppercaseString
is executed, when calling swizzled_uppercaseString
):
#import <objc/runtime.h>
NSString *sample = @"abc";
// original method is called:
NSLog([sample uppercaseString]);
//Obtaining original and swizzled method:
original = class_getInstanceMethod([NSString class], @selector(uppercaseString));
swizzled = class_getInstanceMethod([NSString class], @selector(swizzled_uppercaseString));
//Exchange implementations here:
method_exchangeImplementations(original, swizzled);
// swizzled method is called:
NSLog([sample uppercaseString]); //prints "ABC (swizzled)"
ISA swizzling modifies a property on a single object, the ISA ('is a') property, which describes the class of an object, so you can exchange the type of a given single object with another type at runtime.
Example: Let's assume you have this class structure:
@interface Sample : NSObject
@property (nonatomic) NSString *sampleStringToLoad;
@end
@implementation Sample
@synthesize sampleStringToLoad;
@end
@interface SampleWithStringLoader :NSObject
@property (nonatomic) NSString *sampleStringToLoad;
-(void)loadString;
@end
@implementation SampleWithStringLoader
@synthesize sampleStringToLoad;
-(void)loadString {
self.sampleStringToLoad = @"abc";
}
@end
You can then set the class to SampleWithStringLoader
, so the sampleStringToLoad
-method becomes available:
#import <objc/runtime.h>
Sample *sample = [Sample new];
// switch isa to new class:
object_setClass(sample, [SampleWithStringLoader class]);
// invoke method that is only in SampleWithStringLoader:
[sample performSelector:@selector(loadString)];
// switch isa back to original class:
object_setClass(sample,[Sample class]);
// Prints 'abc':
NSLog(sample.sampleStringToLoad);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With