You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在B类中获取A类实例的变量名并加入数组?

核心结论

直接在类B中获取类A实例的变量名(比如var name = ClassA()里的name)没有原生的直接方法——因为Swift编译后变量名会被优化,运行时通常不会保留这些符号信息。但可以通过以下几种间接方式实现需求:

方法1:创建实例时主动传递变量名

最可靠可控的方式是初始化类A时,把变量名作为参数传入,再让类B从类A实例中读取这个名字:

class ClassA {
    var instanceName: String?
    init(instanceName: String? = nil) {
        self.instanceName = instanceName
    }
}

class ClassB {
    var nameArray: [String] = []
    
    func addInstanceName(from aInstance: ClassA) {
        if let name = aInstance.instanceName {
            nameArray.append(name)
        }
    }
}

// 使用示例
var myInstance = ClassA(instanceName: "myInstance")
let b = ClassB()
b.addInstanceName(from: myInstance)
print(b.nameArray) // 输出 ["myInstance"]

这种方式完全不需要依赖运行时特性,逻辑清晰,适合绝大多数场景。

方法2:利用运行时API获取属性名(仅适用于类属性)

如果类A实例是某个父类的属性,可以通过Objective-C运行时API获取该属性的名称,但仅支持标记为@objc的类:

import ObjectiveC

@objcMembers
class ParentClass: NSObject {
    var userA: ClassA = ClassA()
}

class ClassB {
    var nameArray: [String] = []
    
    func extractPropertyName(from parent: ParentClass, for key: ReferenceWritableKeyPath<ParentClass, ClassA>) {
        let propertyName = NSStringFromSelector(Selector(key.rawValue))
        nameArray.append(propertyName)
    }
}

// 使用示例
let parent = ParentClass()
let b = ClassB()
b.extractPropertyName(from: parent, for: \.userA)
print(b.nameArray) // 输出 ["userA"]

注意:这种方法只能获取类属性的名称,无法获取局部变量的名字。

方法3:用反射(Mirror)遍历属性

通过Mirror可以遍历对象的属性列表,筛选出类A实例对应的属性名,同样仅适用于类属性:

class ParentClass {
    var itemA: ClassA = ClassA()
    var orderA: ClassA = ClassA()
}

class ClassB {
    var nameArray: [String] = []
    
    func collectAInstanceNames(from parent: ParentClass) {
        let mirror = Mirror(reflecting: parent)
        for child in mirror.children {
            if let label = child.label, child.value is ClassA {
                nameArray.append(label)
            }
        }
    }
}

// 使用示例
let parent = ParentClass()
let b = ClassB()
b.collectAInstanceNames(from: parent)
print(b.nameArray) // 输出 ["itemA", "orderA"]

这种方式不依赖Objective-C运行时,但同样无法获取局部变量的名称。

关键提醒
  • 如果var name = ClassA()是局部变量,它的名称在编译后会被编译器彻底优化掉,运行时没有任何方法能获取到name这个字符串。
  • 优先选择方法1,它的逻辑最直观,不会引入运行时或反射带来的不确定性。

内容的提问来源于stack exchange,提问作者Vladislav Zhelezniak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:05:34