加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在Swift中是否可以在运行时向对象添加变量?

发布时间:2020-12-14 05:48:55 所属栏目:百科 来源:网络整理
导读:具体来说,我想将一个enum类型的变量添加到UIView的实例中,而不进行子类化或创建扩展. 谢谢. 关于objc_setAssociatedObject()的前一个答案是正确的方法,但我认为Apple的API尚未经过审查,因为我很难以我认为应该使用它们的方式使用它们. (我不应该用不安全的指
具体来说,我想将一个enum类型的变量添加到UIView的实例中,而不进行子类化或创建扩展.

谢谢.

关于objc_setAssociatedObject()的前一个答案是正确的方法,但我认为Apple的API尚未经过审查,因为我很难以我认为应该使用它们的方式使用它们. (我不应该用不安全的指针等等.)这是我现在使用的解决方案.

首先,您需要一些Objective-C粘合剂(遵循Apple的说明,在同一个项目中混合使用Objective-C和Swift:

// RuntimeGlue.h
// Should be included from your bridging header.

@import Foundation;

void setAssociatedObject_glue(NSObject *object,const NSString *key,NSObject *value);
NSObject *getAssociatedObject_glue(NSObject *object,const NSString* key);


// RuntimeGlue.m

#import "RuntimeGlue.h"
#import <objc/runtime.h>

void setAssociatedObject_glue(NSObject *object,NSObject *value) {
    objc_setAssociatedObject(object,(__bridge const void *)(key),value,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

NSObject *getAssociatedObject_glue(NSObject *object,const NSString* key) {
    return objc_getAssociatedObject(object,(__bridge const void *)(key));
}

接下来,您将从程序的其余部分调用Swift方法:

// Runtime.swift

import Foundation

public func setAssociatedObject(#object: NSObject,#key: NSString,#value: NSObject?) {
    setAssociatedObject_glue(object,key,value)
}

public func getAssociatedObject(#object: NSObject,#key: NSString) -> NSObject? {
    return getAssociatedObject_glue(object,key)
}

最后,用于将特定视图控制器的视图标记为“调试”的示例.

// MyViewController.swift

import UIKit

let debugKey: NSString = "DebugKey"

class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        setAssociatedObject(object: self.view,key: debugKey,value: "debugging")
    }

    override func viewWillAppear(animated: Bool)  {
        super.viewWillAppear(animated)

        let val = getAssociatedObject(object: self.view,key: debugKey)
        println("val:(val)")
    }
}

此方法允许您将nil for value传递给setter以清除键的值,并从getter返回一个可选项.另请注意,关键参数在两种情况下必须相同(k1 === k2),而不仅仅等效(k1 == k2).

另请注意,这只允许您标记NSObject或其子类的实例 – 它不适用于Swift本机类.该值也必须是NSObject子类,但字符串和数字文字都自动桥接到Objective-C,因此您不需要进行任何显式转换.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读