Мой isa-swizzling ломает КВО

Я пытаюсь реализовать isa swizzling, потому что мне нужно, чтобы некоторые действия происходили в методе Dealloc определенного объекта. Я переопределяю - (Класс) класс; метод для возврата исходного класса (как это делает KVO). Все работает нормально, пока я не пытаюсь добавить наблюдателя к swizzled объекту. Он просто падает.

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

Вот реализация swizzling

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

person Denis Mikhaylov    schedule 27.06.2012    source источник
comment
Вы добавляете наблюдателя к объекту до или после свизлинга класса?   -  person Justin Spahr-Summers    schedule 30.06.2012
comment
KVO также реализован с использованием метода swizzling isa, так что неудивительно, что КВО перестает работать после ваших спиверий   -  person nalexn    schedule 27.02.2014


Ответы (1)


Вы должны проверить, как Майк Эш справляется с этим: https://github.com/mikeash/MAZeroingWeakRef

Резюме: обработка подкласса с использованием KVO по-другому - вам придется исправить методы KVO в подклассе KVO...

person nielsbot    schedule 05.02.2013