在Swift中为文字值设置关联对象

Pha*_*oan 1 ios swift

好吧,这可能是一个重复的问题.
我发现了一些像这样的问题: 有没有办法在Swift中设置相关对象?

但是,我想在Intswift中添加一个属性extension,上面链接中的这些答案不起作用.

这是我的代码:

import ObjectiveC
var xoAssociationKey: UInt8 = 0

extension NSData {

    var position: Int {
        get {
            return objc_getAssociatedObject(self, &xoAssociationKey) as Int
        }
        set {
            objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
        }
    }

    override convenience init() {
        self.init()
        position = 0
    }
}
Run Code Online (Sandbox Code Playgroud)

fatal error: unexpectedly found nil while unwrapping an Optional value每次访问都会得到position

仅供参考,我确实在Objective C中找到了这个错误的解决方案,我正在寻找一个快速的解决方案.如果您感兴趣,这是我在目标C中的代码:

static char PROPERTY_KEY;

@implementation NSData (Extension)
@dynamic position;
- (NSInteger)position {
    return  [objc_getAssociatedObject(self, &PROPERTY_KEY) integerValue];
}
- (void)setPosition:(NSInteger)position {
    // Must convert to an object for this trick to work
    objc_setAssociatedObject(self, &PROPERTY_KEY, @(position), OBJC_ASSOCIATION_COPY);
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.position = 0;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 5

NSData 是类集群的一部分,因此不一定要调用自定义init方法,例如

let d = NSMutableData()
Run Code Online (Sandbox Code Playgroud)

不使用你的init方法.接下来的问题是你的init方法以递归方式调用自身

let d = NSData()
Run Code Online (Sandbox Code Playgroud)

堆栈溢出崩溃.另请注意,Objective-C代码依赖于未定义的行为,因为它替换了类扩展中的方法.

因此,最好删除自定义初始化,如果尚未设置关联对象,则更改getter以返回默认值.使用可选的cast(as? Int)和nil-coalescing运算符(??)可以很容易地实现这一点:

extension NSData {

    var position: Int {
        get {
            return objc_getAssociatedObject(self, &xoAssociationKey) as? Int ?? 0
        }
        set {
            objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)