Ошибка миграции SWIFT 3.0. Расширение общего класса Obj-C не может получить доступ к универсальному параметру класса во время выполнения
У меня этот код отлично работает в Swift 2.
extension PHFetchResult: Sequence {
public func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self)
}
}
Так как я обновился до Swift 3
Расширение общего класса Objective-C не может получить доступ к универсальным параметрам класса во время выполнения
Я понятия не имею, как это исправить. Любая помощь очень ценится!
Ответы
Ответ 1
Проблема была представлена здесь: https://bugs.swift.org/browse/SR-1576
Но в конце вы не можете использовать for in
с PHFetchResult в Swift 3.0. Рассмотрим некоторые примеры:
let collections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: nil)
let collectionLists = PHCollectionList.fetchCollectionLists(with: .momentList, subtype: .momentListYear, options: nil)
let assets = PHAsset.fetchAssets(with: .image, options: nil)
Вы можете использовать встроенное перечисление PHFetchResult (мое рекомендуемое решение):
collections.enumerateObjects(_:) { (collection, count, stop) in
//...
}
collectionLists.enumerateObjects(_:) { (collectionList, count, stop) in
//...
}
assets.enumerateObjects(_:) { (asset, count, stop) in
//...
}
Или доступ к каждому объекту по его индексу:
for idx in 0 ..< collections.count {
let collection = collections[idx]
// ...
}
for idx in 0 ..< collectionLists.count {
let collectionList = collectionLists[idx]
// ...
}
for idx in 0 ..< assets.count {
let asset = assets[idx]
// ...
}
Ответ 2
Вытягивая из Realm, вы можете обойти это, расширив подкласс того, что вы хотите подчинить Sequence, и поместите туда функцию makeIerator
.
// Sequence conformance for ClassA is provided by ProtocolX `makeIterator()` implementation.
extension ClassA: Sequence {}
extension ProtocolX {
// Support Sequence-style enumeration
public func makeIterator() -> RLMIterator {
return RLMIterator(collection: self)
}
}
Вы можете увидеть полный код в https://github.com/realm/realm-cocoa/blob/master/Realm/Swift/RLMSupport.swift
Ответ 3
Вы можете использовать тип оболочки как предложенный инженером Swift Jordan Rose в отчете об ошибке:
import Photos
struct ResultSequence<Element: AnyObject>: Sequence {
var result: PHFetchResult<Element>
init(_ result: PHFetchResult<Element>) {
self.result = result
}
func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self.result)
}
}
func test(_ request: PHFetchResult<PHCollection>) {
for elem in ResultSequence(request) {
print(elem)
}
}
Ответ 4
Невозможно исправить это, вам может понадобиться реорганизовать ваш код или использовать другие методы.
вы можете обратиться к этому:
Как использовать быстрый класс с общим типом в объекте c
документы:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_78