5

特定のオブジェクトのdeallocメソッドで何らかのアクションが発生する必要があるため、私はisa swizzlingを実装しようとしています。私は(クラス)クラスをオーバーライドしています。元のクラスを返すメソッド(KVOのように)。観察されるオブジェクトにオブザーバーを追加しようとするまで、すべてうまく動作します。それはちょうどクラッシュします。 【:forProperty:オプション:コンテキスト:NSObjectの(NSKeyValueObserverRegistration)_addObserver]() isa-swizzling breaks KVO

  • 0x0092d6fdに - - [NSObjectの0x00000000の()内 _NSKeyValueRetainedObservationInfoForObject()
  • 0x0092ec88で
  • 0x0091d22aで

    1. 0x00000000の(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これは単なるコンビニエンスな方法でのクラス保持メソッドです(これと生の関数を追加することに違いはありません)。

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

    EDIT:

    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

    クラスをスウィズリングする前または後にオブザーバをオブジェクトに追加していますか? –

    +0

    KVO [isa swizzling techniqueを使用して実装されています](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOImplementation.html)、KVOが停止するのは驚くことではありませんあなたの派遣後に働く – NAlexN

    答えて

    3

    あなたはマイクアッシュは、この処理方法をチェックアウトする必要があります:

    ここclass_addMethodFromClass機能の実装ですhttps://github.com/mikeash/MAZeroingWeakRef

    概要:KVO-スウィズルサブクラスをスウィズル扱います別の方法として、KVOのサブクラスでKVOメソッドにパッチを適用する必要があります。