为什么这是一个保留周期?
Why is this a retain cycle?
我对ARC有基本的了解,但在下面的例子中突然感到很困惑。
FeedViewController
有一个对 NetworkHelper
的强引用,然后 NetworkHelper
有一个函数需要一个闭包并稍后调用它。
所以这里是混乱:
闭包是从FeedViewController
传递给NetworkHelper
,而这个block并没有被保留在NetworkHelper
里面,那为什么NetworkHelper
强引用了NetworkHelper
呢?这是在一篇文章中陈述的,但我只是不明白为什么。只有 NetworkHelper
保持对该块的强引用才对我有意义。
class NetworkHelper {
func getFeed(completion: @escaping ([FeedItem]) -> Void) {
Alamofire.request(…).responseJSON { (response) in
if let value = response.result.value {
if let json = JSON(value)[Constants.items].array {
completion(json.flatMap(FeedItem.init))
}
}
}
}
}
class FeedViewController {
var tableView: UITableViewController
var feedItems: [FeedItem]
var networkHelper: NetworkHelper
override func viewDidLoad() {
...
networkHelper.getFeed() { items in
self.feedItems = items
self.tableView.reloadData()
}
}
}
从技术上讲,没有循环。
首先,NetworkHelper
从不拥有任何东西,它只是将一个闭包传递给Alamofire
。
Alamofire
持有那个闭包,它保留了一个 FeedViewController
实例(如 self
)。但是,Alamofire
不属于 FeedViewController
,因此没有循环。
虽然请求是 运行,但 FeedViewController
确实无法解除分配,因为完成回调会阻止这种情况发生,但这可能是预期的行为,而且绝对没有所有权周期。
我对ARC有基本的了解,但在下面的例子中突然感到很困惑。
FeedViewController
有一个对 NetworkHelper
的强引用,然后 NetworkHelper
有一个函数需要一个闭包并稍后调用它。
所以这里是混乱:
闭包是从FeedViewController
传递给NetworkHelper
,而这个block并没有被保留在NetworkHelper
里面,那为什么NetworkHelper
强引用了NetworkHelper
呢?这是在一篇文章中陈述的,但我只是不明白为什么。只有 NetworkHelper
保持对该块的强引用才对我有意义。
class NetworkHelper {
func getFeed(completion: @escaping ([FeedItem]) -> Void) {
Alamofire.request(…).responseJSON { (response) in
if let value = response.result.value {
if let json = JSON(value)[Constants.items].array {
completion(json.flatMap(FeedItem.init))
}
}
}
}
}
class FeedViewController {
var tableView: UITableViewController
var feedItems: [FeedItem]
var networkHelper: NetworkHelper
override func viewDidLoad() {
...
networkHelper.getFeed() { items in
self.feedItems = items
self.tableView.reloadData()
}
}
}
从技术上讲,没有循环。
首先,NetworkHelper
从不拥有任何东西,它只是将一个闭包传递给Alamofire
。
Alamofire
持有那个闭包,它保留了一个 FeedViewController
实例(如 self
)。但是,Alamofire
不属于 FeedViewController
,因此没有循环。
虽然请求是 运行,但 FeedViewController
确实无法解除分配,因为完成回调会阻止这种情况发生,但这可能是预期的行为,而且绝对没有所有权周期。