在AnyObject或Any上键入约束(任何符合协议的AnyObject或Any)

CjC*_*oax 10 swift

我正在尝试将我的Objective-C代码转换为swift.在Objective-C中,我有以下协议:

@protocol RWOverlaySelectionDelegate <NSObject>
    -(void)areaSelected:(UIView *)view allPoints:(NSArray *)points;
@end
Run Code Online (Sandbox Code Playgroud)

并且下面的类具有引用协议的弱属性(显然它被定义为弱以防止强引用循环).

@interface RWMapSelectionLayer : UIView
    @property(weak, nonatomic) id <RWOverlaySelectionDelegate> delegate;
@end
Run Code Online (Sandbox Code Playgroud)

现在Swift相当于:

协议:

protocol RWOverlaySelectionDelegate {
    func areaSelected(view:UIView,points:CGPoint[])
}
Run Code Online (Sandbox Code Playgroud)

以及具有符合该协议的属性的类:

class RWMapSelectionLayer:NSObject {
    weak var delegate:RWOverlaySelectionDelegate?
}
Run Code Online (Sandbox Code Playgroud)

但是我'weak' cannot be applied to non-class type 'RWOverlaySelectionDelegate'在这一行得到了编译时错误:weak var delegate:RWOverlaySelectionDelegate?

然后我尝试将我的属性转换为AnyObject符合RWOverlaySelectionDelegate使用以下语法的属性:

weak var delegate: AnyObject<RWOverlaySelectionDelegate>?
Run Code Online (Sandbox Code Playgroud)

现在我正在干扰Generics和编译器显示:Cannot specialize non-generic type 'AnyObject'错误.

在另一个不成功的尝试我改变它

weak var delegate: AnyObject:RWOverlaySelectionDelegate?
Run Code Online (Sandbox Code Playgroud)

将其读作"Delegate在AnyObject上,其中AnyObject应符合RWOverlaySelectionDelegate"

这又是不正确的,因为在一个语句中有两个冒号(:).

如果有人可以帮助我,我将不胜感激 enforce conformance to a protocol on AnyObject or Any

Ste*_*ord 9

从那时起我就在这个答案中找到了更好的方法.

更新了最近的Swift版本

正如我在对CjCoax的回答的评论中提到的那样,为协议添加前缀@objc可以防止将Swift对象类型(例如枚举和结构)传递给委托方法.

但是,@class_protocol使用协议为协议添加前缀: class将允许此行为,同时允许在弱变量中使用协议,尽管此方法并非没有限制.您只能使类符合任何带有@class_protocol标记的前缀的协议: class(因此名称).我相信这是一个比@objc提供更好的权衡.

protocol MyProtocol : class {
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 在2015年1月的swift中,这是作为`protocol MyProtocolName:class {...}`完成的,而不是使用`@ class_protocol`声明. (2认同)

chr*_*838 9

我相信推荐的解决方案将是一个仅限类的协议(仅适用于最新的Xcode 6测试版,我目前正在使用GM版本).从Swift编程语言协议页面:

您可以通过将class关键字添加到协议的继承列表来将协议采用限制为类类型(而不是结构或枚举).在任何继承的协议之前,class关键字必须始终首先出现在协议的继承列表中:

因此,在您的示例中,您的协议定义如下所示:

protocol RWOverlaySelectionDelegate: class {
    func areaSelected(view:UIView,points:NSArray)
}
Run Code Online (Sandbox Code Playgroud)

通过添加class关键字,编译器不应再抱怨.