Как изобразить метод для обозначительного экземпляра? - PullRequest
0 голосов
/ 23 мая 2019

Класс 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

Когда экземпляр Person вызывается swizzlingMethod, происходит обмен методом sayHi и методом sayHello.

Однако, если экземпляр называется swizzlingMethod, метод этого экземпляра будет заменен:

- (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];
}

Консоль напечатана hello и hello, хотя person2 не звонил swizzlingMethod.

То, что я хочу, это обмен только методом person1. Таким образом, любой способ может помочь достичь этого?

1 Ответ

0 голосов
/ 23 мая 2019

В Xcode 10.2.1 вы можете объявить swizzlingMethod как метод класса и вызвать его как [Person swizzlingMethod] без изменений реализации.Это означает, что этот метод заменяет реализации sayHi и sayHello на все экземпляры Person.Вы не можете сделать это для определенного объекта, см. этот ответ для получения более подробной информации.

Кроме того, у вас есть логическая ошибка, замените class_replaceMethod(self.class, HI_SEL, method_getImplementation(HELLO_METHOD), method_getTypeEncoding(HELLO_METHOD)); на class_replaceMethod(self.class, HELLO_SEL, method_getImplementation(HI_METHOD), method_getTypeEncoding(HI_METHOD));.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...