我的 isa 旋转打破了 KVO



我正在尝试实现 isa 旋转,因为我需要在某个对象的 dealloc 方法中进行一些操作。我正在覆盖 - (类)类;返回原始类的方法(如 KVO 所做的)。一切正常,直到我尝试将观察器添加到旋转的对象。它只是崩溃。

  1. 0x00000000 0x00000000 ()
  2. 0x0091d22a 在_NSKeyValueRetainedObservationInfoForObject ()
  3. 0x0092ec88 in -[NSObject(NSKeyValueObserverRegistration) _addObserver:forProperty:options:context:] ()
  4. 0x0092d6fd in -[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] ()

这是重排的实现

- (void)swizzleClass
{
    NSString *proxyClassName = [NSString stringWithFormat:@"MDSwizzled_%@", NSStringFromClass(self->isa)];
    Class proxyClass = NSClassFromString(proxyClassName);
    if (!proxyClass)
        proxyClass = [self createProxyClassWithName:proxyClassName];
    object_setClass(self, proxyClass);
}
- (Class)createProxyClassWithName:(NSString *)proxyClassName
{
    const char *c_proxyClassName = [proxyClassName cStringUsingEncoding:NSUTF8StringEncoding];
    Class proxyClass = objc_allocateClassPair(self->isa, c_proxyClassName, 0);
    Class dummyClass = [MDDummy class];
    class_addMethodFromClass(proxyClass, dummyClass, @selector(dealloc));
    class_addMethodFromClass(proxyClass, dummyClass, @selector(class));
    objc_registerClassPair(proxyClass);
    return proxyClass;
}

MDDummy 它只是一种以 convinietn 方式保存的类方法(这和添加原始函数之间没有区别)。

@implementation MDDummy
- (void)dealloc
{
    //Special thinngs
    [super dealloc];
}
- (Class)class
{
    return //original class;
}
@end

编辑:

以下是class_addMethodFromClass函数的实现:

void class_addMethodFromClass(Class class, Class sourceClass, SEL selector)
{
    Method method = class_getInstanceMethod(sourceClass, selector);
    IMP methodImplementation = method_getImplementation(method);
    const char *types = method_getTypeEncoding(method);
    class_addMethod(class, selector, methodImplementation, types);
}

你应该看看 Mike Ash 是如何处理这个问题的: https://github.com/mikeash/MAZeroingWeakRef

摘要:以不同的方式处理 KVO 重排子类 - 您必须修补 KVO 子类中的 KVO 方法......

相关内容

  • 没有找到相关文章

最新更新