在Swift中按协议查找

时间:2015-07-05 13:58:07

标签: swift protocols

如何在Swift中将协议作为参数传递?

在Objective-C中,我可以这样做:

id <CurrentUserContex> userContex = [ServiceLocator locate:@protocol(CurrentUserContex)];

服务定位器:

+ (id)locate:(id)objectType 

修改

在Qbyte回答尝试使用后:

ServiceLocator.locate(CurrentUserContex.self)

但我得到的是CurrentUserContex.Protocol&#39;不确认协议&#39; AnyObject&#39;

所以我试过了:

ServiceLocator.locate(CurrentUserContex.self as! AnyObject)

但后来我得到了:

Could not cast value of type 'ApplicationName.CurrentUserContex.Protocol' (0x7fec15e52348) to 'Swift.AnyObject' (0x7fec15d3d4f8).

4 个答案:

答案 0 :(得分:1)

协议作为方法参数:

protocol Describable:class{var text:String{get}}
class A:Describable{var text:String;init(_ text:String){self.text = text}}
class B:A{}
class C{}


let a = A("I am a")
let b = B("I am b")
let c = C()

func ofType<T>(instance:Any?,_ type:T.Type) -> T?{/*<--we use the ? char so that it can also return a nil*/
    if(instance as? T != nil){return instance as? T}
    return nil
}

Swift.print(ofType(a,A.self)!.text)//I am a
Swift.print(ofType(a,Describable.self)!.text)//I am a
Swift.print(ofType(b,B.self)!.text)//I am b
Swift.print(ofType(c,C.self))//instance of c

其他一些替代方案:

http://stylekit.org/blog/2016/01/25/Asserting-class-and-protocol/

答案 1 :(得分:0)

如果CurrentUserContex是协议本身的名称,我建议使用此方法:

ServiceLocator.locate(CurrentUserContex.self)

如果CurrentUserContex是一个类型是协议使用的变量:

ServiceLocator.locate(CurrentUserContex)

我希望这能解决你的问题

答案 2 :(得分:0)

在Swift中,你必须传递一个类(所有类都符合AnyObject协议)。所以CurrentUserContex也必须是一个类,您可以使用.self或不使用(不幸的是,我没有足够的参考来告诉您确切使用哪个)。

答案 3 :(得分:0)

尝试

ServiceLocator.locate(CurrentUserContex.self as Protocol)

或(在某些版本中,错误Protocol因某种原因无法识别为AnyObject):

ServiceLocator.locate((CurrentUserContex.self as Protocol) as! AnyObject)