2014-09-22 52 views
10

我正试图解决在Swift中基于闭包的强参考循环。
在下面的代码中,对象由拥有的视图控制器保留。 ProgressHUDUIView,它也由拥有的视图控制器保留。每次调用完成处理程序时,ProgressHUD都会泄漏。当使用新的闭包捕获功能时,声明自己为弱或无主无法解决内存泄漏问题。Swift Closures - 捕捉自我弱

object.setCompletionHandler { [weak self] (error) -> Void in 
    if(!error){ 
     self?.tableView.reloadData() 
    } 
    self?.progressHUD?.hide(false) 
} 

但是,如果我宣布一个弱无功为关闭之外的自我,它修复了内存泄漏,就像这样:

weak var weakSelf = self 
object.setCompletionHandler { (error) -> Void in 
    if(!error){ 
     weakSelf?.tableView.reloadData() 
    } 
    weakSelf?.progressHUD?.hide(false) 
} 

任何想法,这是为什么不与斯威夫特拍摄工作?

+0

不应该有一个保留周期 – newacct 2014-10-15 00:41:41

回答

-3

尝试以下操作:

object.setCompletionHandler { [unowned self] (error) ->() in 
    if(!error){ 
     weakSelf?.tableView.reloadData() 
    } 
    weakSelf?.progressHUD?.hide(false) 
} 
+0

正如原文章中指出,无论是弱或无主解决了内存泄漏。不过谢谢。 – 2014-10-14 10:57:27

11

如果您分配一个闭合的类实例的属性,并关闭参照实例或它的成员捕获实例,您将创建一个有力的参考周期关闭和实例之间。 Swift使用捕获列表来打破这些强大的参考周期。 source Apple

source sketchyTech首先,它明确指出,这整个问题只涉及我们正在分配“封闭的类实例的属性”封是非常重要的。请记住每条规则。 规则:

  1. 使用弱捕捉如果类实例或属性是一个可选
  2. 使用无主如果类实例或属性是不可选的,并且不能设置为无
  3. “你必须...使用in关键字,即使您省略参数名称,参数类型和返回类型“

在回答您的问题时,应该没有保留周期。

4

你说progressHUD由所拥有的视图控制器(个体经营)保留,你引用它在你关闭......所以把它添加到捕获列表,然后在封闭使用拍摄的变量,如下所示:

object.setCompletionHandler { [weak self] (error) -> Void in 
    if(!error){ 
     self?.tableView.reloadData() 
    } 
    self?.progressHUD.hide(false) 
} 
+0

无主的引用被隐式解包,所以'self?.tableView'应该改为'self.tableView'。 – 2016-08-30 12:33:12

+0

你是正确的@zxzxlch,我已经编辑我的解决方案,通过改变无主自我弱自我,并从捕获列表中删除progressHUD。应该没有保留周期。 – dferrero 2016-08-31 19:58:20

-1

这是我怎么一直在做:

object.setCompletionHandler { [weak self] (error) -> Void in 
    if let weakSelf = self { 
     if (!error) { 
      weakSelf.tableView.reloadData() 
     } 

     weakSelf.progressHUD?.hide(false) 
    } 
} 
+3

这完全是倒退。将'weakSelf'重命名为'strongSelf'。 '让'给你一个强有力的参考。 – 2016-05-05 18:37:50