【问题标题】:set associated objects for literal value in Swift在 Swift 中为文字值设置关联对象
【发布时间】:2015-02-22 11:11:45
【问题描述】:

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

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

这是我的代码:

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

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

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

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    NSData 是类簇的一部分,所以不一定要调用你自定义的 init 方法, 例如

    let d = NSMutableData()
    

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

    let d = NSData()
    

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

    所以最好删除您的自定义初始化,并将 getter 更改为 如果关联对象尚未设置,则返回默认值。 这可以通过可选演员 (as? Int) 和 零合并运算符 (??):

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

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-23
      • 1970-01-01
      相关资源
      最近更新 更多