[英]Default implementation of protocol extension in Swift not working
我正在嘗試通過協議將功能添加到NSManagedObject
。 我添加了一個可以正常工作的默認實現,但是當我嘗試使用該協議擴展子類時,即使我添加了默認實現,它也會告訴我它的某些部分尚未實現。
任何人都知道我在做什么錯?
class Case: NSManagedObject {
}
protocol ObjectByIdFetchable {
typealias T
typealias I
static var idName: String { get }
static func entityName() -> String
static func objectWithId(ids:[I], context: NSManagedObjectContext) -> [T]
}
extension ObjectByIdFetchable where T: NSManagedObject, I: AnyObject {
static func objectWithId(ids:[I], context: NSManagedObjectContext) -> [T] {
let r = NSFetchRequest(entityName: self.entityName())
r.predicate = NSPredicate(format: "%K IN %@", idName, ids)
return context.typedFetchRequest(r)
}
}
extension Case: ObjectByIdFetchable {
typealias T = Case
typealias I = Int
class var idName: String {
return "id"
}
override class func entityName() -> String {
return "Case"
}
}
我收到的錯誤是Type Case doesn't conform to protocol ObjectByIdFetchable
非常感謝幫助。
我們將使用一個更按比例縮小的示例(下),以闡明此處出了什么問題。 但是,關鍵的“錯誤”是Case
無法為... where T: NSManagedObject, I: AnyObject
使用默認的objectWithId()
實現... where T: NSManagedObject, I: AnyObject
; 因為類型Int
不符合類型約束AnyObject
。 后者用於表示類類型的實例,而Int
是值類型。
AnyObject
可以代表任何類類型的實例。
Any
可以代表任何類型的實例,包括函數類型。
從語言指南類型轉換 。
隨后, Case
無法訪問blueprinted objectWithId()
方法的任何實現,因此不符合協議ObjectByIdFetchable
。
Foo
默認擴展名T
:s符合Any
作品,因為Int
符合Any
:
protocol Foo {
typealias T
static func bar()
static func baz()
}
extension Foo where T: Any {
static func bar() { print ("bar") }
}
class Case : Foo {
typealias T = Int
class func baz() {
print("baz")
}
}
但是,對於將Foo
擴展到符合AnyObject
T
:s而言,情況並非如此,因為Int
不符合類類型的常規AnyObject
:
protocol Foo {
typealias T
static func bar()
static func baz()
}
/* This will not be usable by Case below */
extension Foo where T: AnyObject {
static func bar() { print ("bar") }
}
/* Hence, Case does not conform to Foo, as it contains no
implementation for the blueprinted method bar() */
class Case : Foo {
typealias T = Int
class func baz() {
print("baz")
}
}
編輯附加內容 :請注意,如果您進行更改(如您在自己的答案中所發布的)
typealias T = Int
成
typealias T = NSNumber
那么自然, Case
可以訪問...的默認實現objectWithId()
, ... where T: NSManagedObject, I: AnyObject
,因為NSNumber
是符合AnyObject
類類型。
最后,請注意上述示例中的關鍵字override
,對於實現協議中設計的方法(例如,上述示例中的entityName()
方法entityName()
是不需要的。 Case
的擴展是協議的擴展(通過實現藍圖類型和方法符合ObjectByIdFetchable
),並不能真正與超類對Case
的子類進行比較(在這種情況下,您可能要覆蓋超類的方法)。
我找到了解決問題的辦法。 我以為是typealias T就是不編譯的原因。 這實際上是不對的,我對AnyObject說的是我,有趣的是Int不是AnyObject。 我必須將Int更改為NSNumber
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.