3

Objective-C クラスから継承する迅速なクラスがあり、動的プロパティがある場合、非常に具体的な問題があります。

ここで、+initialize で、swift(:NSObject) クラスに getter と setter を挿入しています。init オーバーロードから値を設定するときのわずかな問題を除いて、これらは問題なく動作します。

したがって、私の迅速なクラスは次のようになります。

class TestClass: BaseClass {

    dynamic var testStringProperty: String?

    init(initialValue: String) {
        super.init()
        self.testStringProperty = initialValue;
        // does not trigger the get/set methods
        // a po self.testStringProperty will output 'nil'
        let xyz = self.testStringProperty;
        // xyz is actually set to the value of initialValue, but it does not trigger the getter.
    }

}

そして、swift のベースとなる Objective-C クラスは次のとおりです。

static id storedVar;

@implementation BaseClass

+ (void)initialize {
    // we are going to exchange getter/setter methods for a property on a SwiftClass, crude but demonstrates the point
    if(![[self description] isEqualToString:@"BaseClass"]) {

        IMP reader = (IMP)getPropertyIMP;
        IMP writer = (IMP)setPropertyIMP;
        const char* type = "@";
        NSString* propertyName = @"testStringProperty";

        IMP oldMethod = class_replaceMethod([self class], NSSelectorFromString(propertyName), reader, [[NSString stringWithFormat:@"%s@:", type] UTF8String]);
        NSString* setMethod = [NSString stringWithFormat:@"set%@%@:", [[propertyName substringToIndex:1] uppercaseString], [propertyName substringFromIndex:1]];
        oldMethod = class_replaceMethod([self class], NSSelectorFromString(setMethod), writer, [[NSString stringWithFormat:@"v@:%s",type] UTF8String]);

    }
}

static id getPropertyIMP(id self, SEL _cmd) {

    return storedVar;

}

static void setPropertyIMP(id self, SEL _cmd, id aValue) {

    storedVar = aValue;

}

@end

簡単に言うと、 への呼び出し中はinit(initialValue: String)、ゲッターとセッターはトリガーされませんが、init への呼び出しが完了するとすぐに動作します。

これは、initialize の呼び出しが正常に完了し、メソッドが置き換えられているにもかかわらずです。

ただし、init関数の外では、get/set は期待どおりに動作します。

ここでそれが呼び出されます。

let test = TestClass(initialValue: "hello");
test.testStringProperty = "hello"

オブジェクトのpo test.testStringProperty 作成後、nil が出力されます。しかし、その後の割り当てでは、すべての正しいメソッドがトリガーされます。

init 内で割り当てる場合にのみ失敗します。他のどこでも、それは魅力のように機能します。

可能であれば、イニシャライザ内でこれを機能させたいのですが、別の方法で回避できるかどうかはわかりません。

問題を再現するサンプル アプリへのリンクを次に示します。

https://www.dropbox.com/s/5jymj581yps799d/swiftTest.zip?dl=0

4

0 に答える 0