在Swift中迭代弱引用数组,其中对象符合某个协议

4
我希望将符合某个协议且为弱引用的对象存储在一个数组中。但是当我尝试循环它时,会出现编译错误:
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()
}

你知道这是什么意思吗?

Bitcast需要相同宽度的类型 %.asSubstituted = bitcast i64 %35 to i128, !dbg !5442 LLVM错误:发现损坏的函数,编译中止!

输入图像描述 输入图像描述 输入图像描述

3个回答

3

我认为这是编译器的限制/bug。如果你将协议标记为@objc,它就能正常工作,例如:

// 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

使用@objc而不是纯Swift解决方案可能会让人感到烦恼,但由于我在iOS上,这对我来说不是问题。


2

泛型不会按照你想象的方式继承其解析类型的协议。你的Weak<ClassWithReloadFRC> 类型将是普遍无用的。例如,你不能创建一个这样的对象,更别说加载一个它们的数组了。

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

我认为需要问自己的是你真正想要做什么。例如,如果你需要一个弱引用对象数组,Cocoa内置了相应的方法。


1
我应该补充一下,总的来说,我使用Array<ProtocolType>时遇到了很多问题,所以我预计Array<Generic<ProtocolType>>会更糟糕。 :) - matt
有内置的Cocoa方法可以做到这一点 - 它们只在Objective-C中起作用。如果您尝试使用NSHashTable或类似的东西,您将会得到与作者使用Weak包装器时相同的错误。 - kelin

1

我在Xcode 6.4中遇到了类似的编译错误。我需要一个弱协议数组来存储视图控制器的多个代理。根据我找到的类似问题的答案,我使用了NSHashtable而不是swift数组。

private var _delegates = NSHashTable.weakObjectsHashTable()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接