假设我有两个类:
class Foo: NSObject {
var specialProperty: String = "hello"
}
class Bar: NSObject {
var specialProperty: String = "goodbye"
}
现在假设我正在处理一个我知道只包含Foo
和Bar
实例的集合。我知道数组中的每个对象都会响应specialProperty
选择器,所以在Objective-C中我可以像以下一样进行转换:
for id thing in arrayOfThings
{
NSLog(@"specialProperty: %@", ((Foo *)thing).specialProperty);
}
我怎样才能在Swift中解决这个问题?我不能为Foo
和Bar
添加一个共同的超类,也不能为它们添加协议。实际上,Foo
和Bar
是NSManagedObject
子类,代表我的应用程序中的模型项。
我考虑过这种方法:
let collection: [AnyObject] // Assume this contains Foo and Bar instances.
let sel: Selector = #selector(setter: Foo.specialProperty)
for item in collection
{
if item.respondsToSelector(sel)
{
instance.perform(sel, with: "new value")
}
}
将Qazxswpoi的实例调用sel
工作,即使我告诉Swift选择器的类型是Bar
?看起来应该是因为Objective-C选择器机制不关心Object的类是什么;这不是选择器签名的一部分。但我不确定Swift-ObjectiveC交互中是否存在我忽略的内容。
我正在从Objective-C迁移此应用程序。
在Objective C和Swift中,正确的方法是使用协议:
Foo.
我想你也可以考虑这种方法
protocol Special {
var specialProperty { get set }
}
class Foo: NSObject, Special {
var specialProperty: String = "hello"
}
class Bar: NSObject, Special {
var specialProperty: String = "goodbye"
}
let collection: [Special] = ...
for item in collection {
item.specialProperty = "new value"
}
除了使用协议,我相信它也可以使用可选的强制转换来完成
let collection: [AnyObject] // Assume this contains Foo and Bar instances.
for item in collection
{
guard let aFoo = item as? Foo else {
guard let aBar = item as? Bar else { continue }
aBar.specialProperty = "New value"
continue
}
aFoo.specialProperty = "New value"
}