我的混合打破了KVO

时间:2012-06-27 07:11:39

标签: objective-c key-value-observing objective-c-runtime swizzling isa-swizzling

我正在尝试实现isa调配,因为我需要在某些对象的dealloc方法中执行某些操作。我压倒一切 - (班级)班级;返回原始类的方法(如KVO所做)。一切正常,直到我尝试将观察者添加到混合对象。它只是崩溃了。

  1. 0x00000000在0x00000000()
  2. 0x0091d22a in _NSKeyValueRetainedObservationInfoForObject()
  3. 0x0092ec88 in - [NSObject(NSKeyValueObserverRegistration)_addObserver:forProperty:options:context:]()
  4. 0x0092d6fd in - [NSObject(NSKeyValueObserverRegistration)addObserver:forKeyPath:options:context:]()
  5. 这是混合的实现

    - (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它只是一种以持久的方式持有类的方法(这与添加原始函数没有区别)。

    @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);
    }
    

1 个答案:

答案 0 :(得分:4)

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

总结:处理KVO调度子类的方式不同 - 你必须修补KVO子类中的KVO方法......