【问题标题】:How to swizzling method for a designative instance?如何为指定实例调配方法?
【发布时间】:2019-10-09 15:42:01
【问题描述】:

班级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];
}

即使 person2 没有调用 swizzlingMethod,控制台也会打印 hellohello

我想要的只是交换了person1的方法。那么有什么方法可以帮助实现它吗?

【问题讨论】:

    标签: objective-c runtime


    【解决方案1】:

    在 Xcode 10.2.1 中,您可以将 swizzlingMethod 声明为类方法并像 [Person swizzlingMethod] 一样调用它,而无需更改实现。这意味着此方法为Person 的所有实例交换sayHisayHello 的实现。您不能对特定对象执行此操作,请参阅this answer 了解更多详细信息。

    另外,您有一个逻辑错误,请将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));

    【讨论】:

      猜你喜欢
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 2013-01-13
      • 2011-06-11
      • 2010-10-23
      • 2014-11-21
      相关资源
      最近更新 更多