Swift匿名类
Swift中匿名类的等价物。
Swift匿名类为您的项目添加了 _new
功能。
public func _new<Type>(owner: AnyObject? = nil, _ objectCreator:()->Type) -> Type
比如说,您有一个协议
protocol Greeting {
func sayHello() -> String
}
您需要一个能够说“hello”的类。
let object: Greeting = _new {
class NoName: Greeting {
func sayHello() -> String {
return "hello from no name class"
}
}
return NoName()
}
object.sayHello()
更实际的例子
let configuration = URLSessionConfiguration.default
var downloadsSession = URLSession(configuration: configuration,
delegate: _new {
class NoName: NSObject, URLSessionDownloadDelegate {
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL) {
print("Finished downloading to \(location).")
}
}
return NoName()
},
delegateQueue: nil)
注意URLSession会强引用其代理,但通常代理会被弱引用。如果只是使用 some.delegate = _new {...}
,您将得到nil。首先,您需要对其进行强引用。为此,您可以使用 _new
函数的 owner
参数。此参数将 _new
对象的生命周期与 owner
绑定,当调用 owner
的 deinit
方法时,新的匿名对象将被移除。
例子
protocol ADelegate: class {
func `do`()
}
class A {
weak var delegate: ADelegate?
deinit {
delegate?.do()
}
}
...
let a = A()
a.delegate = _new(owner: a) {
class ADelegateInstance: ADelegate {
func `do`() {
print("DO from delegate")
}
}
}
如果您设置了新的匿名代理,第一个将被释放。如果设置了新的代理(而不是使用 _new
),匿名代理将保留直到代理被释放。要强制将其移除,您可以先设置为nil。例如
假设您有一个具有弱代理的Some类和SomeDelegate。您还有SomeDelegate的实例,它的实例被某地强烈引用。首先,您将Some实例的代理设置为一个匿名对象。但后来,您将其更改为非匿名类,匿名类变得不可达但仍然存在。要确保在某个实例释放之前销毁它,您可以执行以下操作
some.delegate = _new(owner:some) {
class NoName: SomeDelegate {
func `do`() {
print("DO")
}
}
return NoName()
}
some.delegate = _new(owner:some) { nil }
some.delegate = someDelegateInstance