0

The class Person:

@implementation Person

- (void)sayHi {
    NSLog(@"hi");
}

- (void)sayHello {
    NSLog(@"hello");
}

- (void)swizzlingMethod {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SEL HI_SEL = @selector(sayHi);
        SEL HELLO_SEL = @selector(sayHello);

        Method HI_METHOD = class_getInstanceMethod(self.class, HI_SEL);
        Method HELLO_METHOD = class_getInstanceMethod(self.class, HELLO_SEL);

        BOOL addSuccess = class_addMethod(self.class, HI_SEL, method_getImplementation(HELLO_METHOD), method_getTypeEncoding(HELLO_METHOD));
        if (addSuccess) {
            class_replaceMethod(self.class, HI_SEL, method_getImplementation(HELLO_METHOD), method_getTypeEncoding(HELLO_METHOD));
        } else {
            method_exchangeImplementations(HI_METHOD, HELLO_METHOD);
        }
    });
}

@end

When Person's instance called swizzlingMethod,method sayHi and method sayHello would be exchanged.

However,once an instance called swizzlingMethod,all the instance's method would be exchange:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    Person *person1 = [Person new];
    [person1 swizzlingMethod];
    [person1 sayHi];

    Person *person2 = [Person new];
    [person2 sayHi];
}

Console printed hello and hello even though person2 didn't call swizzlingMethod.

What I want is only person1's method exchanged.So any way can help to achieve it?

无夜之星辰
  • 5,426
  • 4
  • 25
  • 48

1 Answers1

0

In Xcode 10.2.1 you can declare swizzlingMethod as a class method and call it like [Person swizzlingMethod] without the implementation changes. It means that this method exchanges the implementations of sayHi and sayHello for all instances of Person. You cannot do it for a particular object, see this answer for more details.

Also, you have a logical error, replace class_replaceMethod(self.class, HI_SEL, method_getImplementation(HELLO_METHOD), method_getTypeEncoding(HELLO_METHOD)); with class_replaceMethod(self.class, HELLO_SEL, method_getImplementation(HI_METHOD), method_getTypeEncoding(HI_METHOD));.

Roman Podymov
  • 4,168
  • 4
  • 30
  • 57