Ios 保持对使用闭包[Swift]的本地对象的强引用
我有一个关于保持对使用闭包的本地对象的强引用的问题。 我有下面的代码,其中对象B使用一个闭包类型为a的本地对象的方法。 对象A中的方法使用异步操作执行一些网络任务,然后将闭包返回给对象b。 由于对象A在B中的方法中是本地的,并且由于我在对象A异步任务中使用了[weak self](以防止保留循环),所以对象被释放 我应该在下面的代码中更改什么,以确保只有在完成闭包时才会释放本地对象 这是重要代码的一部分:Ios 保持对使用闭包[Swift]的本地对象的强引用,ios,swift,memory,closures,strong-parameters,Ios,Swift,Memory,Closures,Strong Parameters,我有一个关于保持对使用闭包的本地对象的强引用的问题。 我有下面的代码,其中对象B使用一个闭包类型为a的本地对象的方法。 对象A中的方法使用异步操作执行一些网络任务,然后将闭包返回给对象b。 由于对象A在B中的方法中是本地的,并且由于我在对象A异步任务中使用了[weak self](以防止保留循环),所以对象被释放 我应该在下面的代码中更改什么,以确保只有在完成闭包时才会释放本地对象 这是重要代码的一部分: class A { var restAPI: RestAPI? func
class A {
var restAPI: RestAPI?
func fetchNews(completion: (_ json: [String:Any])->()) {
// .....
self.restAPI.fetch(url: url, results: { [weak self] (json) in //
completion(json)
})
// .....
}
}
class B {
// ....
// ... call to updateNews()
func updateNews() {
let aFetcher: A()
aFetcher.fetchNews(completion : {
// <<<< // aFetcher gets released and closue never called
// parse...
}
}
}
A类{
var restAPI:restAPI?
func fetchNews(完成:(json:[String:Any])->()){
// .....
self.restAPI.fetch(url:url,结果:{[weak self](json)in//
完成(json)
})
// .....
}
}
B类{
// ....
//…调用updateNews()
func updateNews(){
让阿费彻:A()
aFetcher.fetchNews(完成:{
//您将aFetcher声明为func updateNews()范围内的let
当updateNews()的作用域结束时,将释放一个蚀刻器。
您的内部获取函数中有[弱自我]。
在此阶段,将释放一个Etcher,因为updateNews()完成其执行,并且没有对此对象的强引用
您只需要将变量aFetcher添加到类B中,以确保对aFetcher有强引用
在func updateNews()的作用域中将aFetcher声明为let
当updateNews()的作用域结束时,将释放一个蚀刻器。
您的内部获取函数中有[弱自我]。
在此阶段,将释放一个Etcher,因为updateNews()完成其执行,并且没有对此对象的强引用
您只需要将变量aFetcher添加到类B中,以确保对aFetcher有强引用
你需要在班级的顶层有一个强有力的参考
但是,为了不永久保留引用,并可靠地保留和释放引用,请在B类
中添加可选存储属性,并在完成关闭时将其设置为nil
:
class B {
var fetcher : A?
// MARK: - Public
func updateNews() {
fetcher = A()
fetcher!.fetchNews(completion : { [unowned self] in
// parse...
self.fetcher = nil
}
}
}
你需要在班级的顶层有一个强有力的参考
但是,为了不永久保留引用,并可靠地保留和释放引用,请在B类
中添加可选存储属性,并在完成关闭时将其设置为nil
:
class B {
var fetcher : A?
// MARK: - Public
func updateNews() {
fetcher = A()
fetcher!.fetchNews(completion : { [unowned self] in
// parse...
self.fetcher = nil
}
}
}
谢谢大家,但是如果我想让变量是局部的而不是类属性呢?那我该怎么办?事实上,它不是类属性,而是实例属性。然而,你需要一个对类AIMHO的实例的强引用(不能是局部的),这不是一个好的模式。它还带有一个微妙的问题:如果完成处理程序保留对对象的最后一个强引用,当完成处理程序执行时,它将在此线程上被销毁。由于创建它的线程(其中updateNews()
将被调用)可能是另一个线程,这将产生数据争用。为了使它工作,您需要“线程限制”(另一个错误模式),但无论如何,你不需要类B中的var fetcher。谢谢各位,但如果我希望变量是局部的而不是类属性呢?那我该怎么办?实际上它不是类属性,而是实例属性。不过,你需要一个强引用(不能是局部的)来引用类AIMHO的实例,这不是一个好方法它还存在一个微妙的问题:如果完成处理程序保留对对象的最后一个强引用,那么当完成处理程序执行时,它将在此线程上被销毁。因为创建它的线程(其中updateNews()
将被调用)可能是另一个问题,这会产生一场数据竞争。为了让它正常工作,你需要“线程限制”(另一种糟糕的模式),但你无论如何也不需要类B中的var fetcher。实际上,这个问题没有好的解决方案。主要问题是线程安全。你最好定义并初始化变量restAPI
“外面“在必须超过B类实例的A类实例中。您还需要在创建它的同一线程上销毁它。最好在A类实例中再次执行此操作。实际上,此问题没有很好的解决方案。主要问题是线程安全。最好定义并初始化变量restAPI
类实例中的“外部”必须超过类B实例。您还需要在创建它的同一线程上销毁它。最好在类A实例中再次执行此操作。