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
相关产品推荐
相关产品推荐

