5

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

  1. 0x00000000 в 0x00000000()
  2. 0x0091d22a в _NSKeyValueRetainedObservationInfoForObject()
  3. 0x0092ec88 в - [NSObject (NSKeyValueObserverRegistration) _addObserver: forProperty: опции: контекст:]()
  4. 0x0092d6fd в - [NSObject (NSKeyValueObserverRegistration) addObserver: forKeyPath: опции: контекст:]()

Вот реализация 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 Это просто метод удержания класса методом convietn (нет никакой разницы между этим и добавлением сырых функций).

@implementation MDDummy 
- (void)dealloc 
{ 

    //Special thinngs 

    [super dealloc]; 
} 

- (Class)class 
{ 
    return //original class; 
} 
@end 

EDIT:

Вот реализация функции 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); 
} 
+0

Добавляете ли вы наблюдателя к объекту до или после swizzling класса? –

+0

KVO [также реализуется с использованием техники isa swizzling] (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOImplementation.html), поэтому неудивительно, что остановка KVO работать после ваших spivveries – NAlexN

ответ

3

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

Резюме: ручка swizzling с КВО-swizzled подкласса иначе - вам придется исправить методы KVO в подклассе KVO ...