Iterate array of weak references where objects conform to a protocol in Swift

那年仲夏 提交于 2019-12-10 15:16:37

问题


I want to store objects in an array, where objects are weak, and conforms to a protocol. But when I try to loop it, I get a compiler error:

public class Weak<T: AnyObject> {
    public weak var value : T?
    public init (value: T) {
        self.value = value
    }
}

public protocol ClassWithReloadFRC: class {

    func reloadFRC()
}

public var objectWithReloadFRC = [Weak<ClassWithReloadFRC>]()

for owrfrc in objectWithReloadFRC {

    //If I comment this line here, it will able to compile.
    //if not I get error see below
    owrfrc.value!.reloadFRC()
}

Any idea what the heck?

Bitcast requires types of same width %.asSubstituted = bitcast i64 %35 to i128, !dbg !5442 LLVM ERROR: Broken function found, compilation aborted!


回答1:


Generics don't do protocol inheritance of their resolving type in the way that you seem to imagine. Your Weak<ClassWithReloadFRC> type is going to be generally useless. For example, you can't make one, let alone load up an array of them.

class Thing : ClassWithReloadFRC {
    func reloadFRC(){}
}
let weaky = Weak(value:Thing()) // so far so good; it's a Weak<Thing>
let weaky2 = weaky as Weak<ClassWithReloadFRC> // compile error

I think the thing to ask yourself is what you are really trying to do. For example, if you are after an array of weakly referenced objects, there are built-in Cocoa ways to do that.




回答2:


I think there is a compiler limitation/bug. If you mark your protocol as @objc it will work, e.g.:

// Array of weak references of a protocol OK so long as protocol marked @objc
struct WeakReference<T: AnyObject> {
    weak var value: T?
}
@objc protocol P { // Note @objc, class or AnyObject won't work
    var i: Int { get }
}
class CP: P {
    var i: Int = 0
}
let cP = CP() // Strong reference to prevent collection
let weakPs: [WeakReference<P>] = [WeakReference(value: cP)] // Note typed as `[WeakReference<P>]`
print("P: \(weakPs[0].value!.i)") // 0

It is annoying that you have to use @objc and therefore not a pure Swift solution, but since I am on iOS not a problem for me.




回答3:


I was seeing a similar compiler error in Xcode 6.4. I needed an array of weak protocols to store multiple delegates for a view controller. Based on an answer to a similar question I found, I used a NSHashtable instead of a swift array.

private var _delegates = NSHashTable.weakObjectsHashTable()


来源:https://stackoverflow.com/questions/31189184/iterate-array-of-weak-references-where-objects-conform-to-a-protocol-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!