2014-06-05 45 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 
} 
相關問題