Swift:对具有相同选择器的对象进行类型转换

问题描述 投票:0回答:3

The Situation

假设我有两个类:

class Foo: NSObject {
    var specialProperty: String = "hello"
}

class Bar: NSObject {
    var specialProperty: String = "goodbye"
}

现在假设我正在处理一个我知道只包含FooBar实例的集合。我知道数组中的每个对象都会响应specialProperty选择器,所以在Objective-C中我可以像以下一样进行转换:

for id thing in arrayOfThings
{
    NSLog(@"specialProperty: %@", ((Foo *)thing).specialProperty);
}

我怎样才能在Swift中解决这个问题?我不能为FooBar添加一个共同的超类,也不能为它们添加协议。实际上,FooBarNSManagedObject子类,代表我的应用程序中的模型项。


Selector?

我考虑过这种方法:

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交互中是否存在我忽略的内容。


Context

我正在从Objective-C迁移此应用程序。

objective-c swift casting selector
3个回答
4
投票

在Objective C和Swift中,正确的方法是使用协议:

Foo.

3
投票

我想你也可以考虑这种方法

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

0
投票

除了使用协议,我相信它也可以使用可选的强制转换来完成

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"
}
© www.soinside.com 2019 - 2024. All rights reserved.