我试图将Objective-C代码转换为swift。 在Objective-C中,我有以下协议:
@protocol RWOverlaySelectionDelegate <NSObject>
-(void)areaSelected:(UIView *)view allPoints:(NSArray *)points;
@end
以下类具有引用协议的弱属性(显然它被定义为弱以防止强引用循环)。
@interface RWMapSelectionLayer : UIView
@property(weak, nonatomic) id <RWOverlaySelectionDelegate> delegate;
@end
现在是Swift的等价物:
协议:
protocol RWOverlaySelectionDelegate {
func areaSelected(view:UIView,points:CGPoint[])
}
以及具有符合该协议的属性的类:
class RWMapSelectionLayer:NSObject {
weak var delegate:RWOverlaySelectionDelegate?
}
但我在此行中收到'weak' cannot be applied to non-class type 'RWOverlaySelectionDelegate'
编译时错误:weak var delegate:RWOverlaySelectionDelegate?
然后我尝试使用以下语法将我的属性转换为符合AnyObject
的{{1}}:
RWOverlaySelectionDelegate
现在我干扰了Generics和编译器显示:weak var delegate: AnyObject<RWOverlaySelectionDelegate>?
错误。
在另一次失败的尝试中,我将其更改为
Cannot specialize non-generic type 'AnyObject'
将其读作&#34; Delegate的类型为AnyObject,其中AnyObject应符合RWOverlaySelectionDelegate&#34;
由于单个语句中有两个冒号(:),这又是不正确的。
如果有人可以帮我weak var delegate: AnyObject:RWOverlaySelectionDelegate?
答案 0 :(得分:9)
我已经在this answer找到了更好的方法。
针对最近的Swift版本进行了更新
正如我在对CjCoax答案的评论中提到的,在协议前加上@objc
会阻止将Swift对象类型(例如枚举和结构)传递给委托方法。
然而,使用@class_protocol
使用: class
为协议添加前缀将允许此行为,同时允许在弱变量中使用协议,尽管此方法并非没有限制。您只能使类符合任何前缀为且标有@class_protocol
: class
的协议(因此名称)。我相信这是一个比@objc
提供的更好的权衡。
protocol MyProtocol : class {
...
}
答案 1 :(得分:9)
我认为推荐的解决方案是仅限课程的协议(仅适用于最新的Xcode 6测试版,我目前正在使用GM版本)。从Swift Programming Language协议页面:
通过将class关键字添加到协议的继承列表,可以将协议采用限制为类类型(而不是结构或枚举)。在任何继承的协议之前,class关键字必须始终首先出现在协议的继承列表中:
因此,在您的示例中,您的协议定义如下所示:
protocol RWOverlaySelectionDelegate: class {
func areaSelected(view:UIView,points:NSArray)
}
通过添加class关键字,编译器不应再抱怨了。
答案 2 :(得分:1)
由于swift 4而不是class,我们应该使用AnyObject。来自Swift编程语言protocol page:
您可以将协议采用限制为类类型(而不是结构或类型) 枚举)通过将AnyObject协议添加到协议的 继承清单。
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
答案 3 :(得分:0)
找到解决方案: 我只需要声明我的协议如下:
@objc protocol RWOverlaySelectionDelegate {
func areaSelected(view:UIView,points:NSArray)
}
然后该类只使用协议名称而不是符合协议的AnyObject
class RWMapSelectionLayer:NSObject {
weak var delegate: RWOverlaySelectionDelegate?;
}
@objc protocol RWOverlaySelectionDelegate
的协议声明要求RWOverlaySelectionDelegate
的对象成为一个类。
以下是Apple提供的The Swift Programing Language
指南的参考资料
@objc协议只能由类
采用