Is swizzling and isa swizzling the same way?

Is the swizzling and isa swizzling method the same? If not, then what is swasling?

+4
source share
1 answer

Swizzling method

The swizzling method replaces the implementation of two class methods at runtime . This will affect every instance that was or will be created, of the modified class.

Example: Suppose you wrote 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

uppercaseString swizzled_uppercaseString, swizzled_uppercaseString , uppercaseString. ( uppercaseString 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

ISA swizzling , ISA ('is a'), , .

: , :

@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

SampleWithStringLoader, sampleStringToLoad :

#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);  
+17

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


All Articles