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

时间:2014-12-24 10:06:29

标签: ios swift

嗯,这可能是一个重复的问题。
我发现了一些像这样的问题: Is there a way to set associated objects in Swift?

但是,我想在swift的Int中添加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
    }
}

每次访问fatal error: unexpectedly found nil while unwrapping an Optional value时,我都会position

仅供参考,我确实在目标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;
}

1 个答案:

答案 0 :(得分:5)

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

let d = NSMutableData()

不使用您的init方法。下一个问题是你的init方法调用 因此递归地,

let d = NSData()

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

因此,最好删除自定义初始化,并将getter更改为 如果尚未设置关联对象,则返回默认值。 这可以通过可选的强制转换(as? Int)和 nil-coalescing operator(??):

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