2014-06-05 41 views
9

我试图将我的Objective-C代码转换为swift。 在Objective-C I有如下方案:对AnyObject或任何类型约束(AnyObject或任何符合协议)

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

和以下类有引用该协议(显然它定义为弱以防止发生强基准周期)的弱属性。

@interface RWMapSelectionLayer : UIView 
    @property(weak, nonatomic) id <RWOverlaySelectionDelegate> delegate; 
@end 

现在斯威夫特相当于:

协议:

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符合RWOverlaySelectionDelegateCannot specialize non-generic type 'AnyObject'错误:

weak var delegate: AnyObject<RWOverlaySelectionDelegate>? 

现在,我与泛型和编译器显示的干扰。

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

weak var delegate: AnyObject:RWOverlaySelectionDelegate? 

它读作“代表是类型AnyObject其中AnyObject应符合RWOverlaySelectionDelegate”

这是因为两个冒号的再次不正确(:)在一个单一的声明。

希望如果有人能帮助我enforce conformance to a protocol on AnyObject or Any

回答

9

采纳我后来发现this answer这样做的更好的方法。

更新了最新版本的雨燕

正如我在上CjCoax的答案评论中提及,与@objc防止通过斯威夫特对象类型(如枚举和结构),以委托方法前缀的协议。

然而 前缀协议使用 : class将允许这种行为,同时允许在弱变量,使用的协议,但这种方法也不是没有它的局限性 @class_protocol 。您只能使课程符合 前缀 @class_protocol 的所有协议,并标记为: class(因此名称)。我相信这是一个比@objc提供的更好的折衷。

protocol MyProtocol : class { 
    ... 
} 
+2

在2015年1月的swift中,这是通过'protocol MyProtocolName:class {...}'完成的,而不是使用'@ class_protocol'声明。 –

0

找到了解决办法: 我只需要声明我的协议如下:

@objc protocol RWOverlaySelectionDelegate { 
    func areaSelected(view:UIView,points:NSArray) 
} 

,然后类只使用协议的名称,而不是AnyObject符合协议

class RWMapSelectionLayer:NSObject { 
    weak var delegate: RWOverlaySelectionDelegate?; 
} 

协议声明是@objc protocol RWOverlaySelectionDelegate要求RWOverlaySelectionDelegate的对象是一个类。 这里是The Swift Programing Language导游苹果提供的参考

@objc协议只能由类

+2

与做这是你不能再传给斯威夫特,只有类型的委托方法(如枚举和结构)的问题。 –

+0

@SteveWilford,同意,只需要坚持下去,直到我找到一种方法来声明一个限制实现一个协议的属性。 – CjCoax

9

我相信推荐的解决方案将是唯一一类协议(仅在最近的Xcode 6个测试版可用,我目前使用的通用版本)。从Swift Programming Language协议页:

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

所以,在你的榜样,你的协议定义看起来像:

protocol RWOverlaySelectionDelegate: class { 
    func areaSelected(view:UIView,points:NSArray) 
} 

由于添加了class关键字,编译器不应再抱怨。

+0

这应该是现在接受的答案(截至Xcode 6.1 GM) –

1

由于swift 4而不是类,我们应该使用AnyObject。从斯威夫特编程语言protocol page

您可以通过添加AnyObject协议,协议的 继承列表限制协议采用类类型(而不是结构或 枚举)。

protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol { 
    // class-only protocol definition goes here 
} 
相关问题