2017-01-01 43 views
1

对不起,但我知道这是一个非常愚蠢的问题,我已经“知道”了答案,但我需要有人向我明确解释为什么答案就是这样。为什么不引用一个函数之外创建保留循环?

最近,我经历了一些有关各种内存问题的恶梦调试之后,对代码中的保留周期和内存泄漏有点痴迷/偏执,所以将来我想将它们扼杀在萌芽状态。但是,在阅读并学习了许多关于ARC并在Swift中保留循环之后,尽管它很有意义,但我仍然没有足够的“直觉”或自然的感觉,以确信我能找到一个,或者缺乏一个,因为我在编码。所以我开始变得有点偏执狂,即使我没有意识到这一点,我甚至会用基本的东西来创建保留周期。

因此,考虑到这一点,为什么没有任何使用声明的变量的普通函数创建保留周期?例如:

class someClass { 
     let a = "I'm letter a" 
     let moreLetters = addLetters() 
     func addLetters() -> String { 
      let newString = a + "bcdefg" 
      return newString 
     } 
    } 

在这种情况下,self.moreLetters引用功能addLetters,然后恒定self.a是从功能addLetters内​​引用。那么如果我不抓住弱/无主的自我,这会创造一个保留周期吗?对我来说,这种简单的事会导致问题似乎是荒谬的......或者它是什么?在嵌套函数中怎么样,像这样:

func someFunction() -> String { 
     let a = "I'm letter a" 
     func addLetters() -> String { 
      let newString = a + "bcdefg" 
      return newString 
     } 
     let moreLetters = addLetters() 
     return moreLetters 
    } 

这是否也会创建保留循环? (是的,我知道这是一个执行简单任务的复杂方式;我只是用这个代码作为例子来说明我的观点)。

我是否变得超级偏执狂,并且正在严重推翻事物?

+0

'let moreLetters = addLetters()'编译错误。 – bubuxu

+0

在Swift中,字符串是值类型而不是引用类型,因此在您的示例中不会出现引用循环。你可以使用参考类型来更改你的问题吗? –

回答

2

首先,您需要了解基本保留周期是如何形成的。当对象A强烈且同时引用对象B时形成保留周期。对象B也强烈地指向对象A.

让我们来看看你的第一个代码。

class someClass { 
    let a = "I'm letter a" 
    let moreLetters = addLetters() 
    func addLetters() -> String { 
     let newString = a + "bcdefg" 
     return newString 
    } 
} 

其实,一类本身不能创造保留周期,所以让我们添加一些代码来创建一个对象:

var obj = someClass() 

首先,a被初始化为“我是信了”。之后,moreLetters通过调用方法addLetters进行初始化。方法返回后,moreLetters被初始化为“我是字母abcdefg”。到现在为止还挺好。

现在我们设置objnil

obj = nil 

如果形成一个保留周期,obj不会deinitialized。但是,实际上,obj被初始化,因为没有任何内容对obj有强烈的参考!

“等一下!”你说,“但方法addLetters仍然指someClass,因为它里面有a!”那么,其实addLetters已经回来了!因此,它里面的一切都无所谓了!另外,addLetters属于obj,您已经设置为nil

现在,让我们看看你的第二个代码:

func someFunction() -> String { 
    let a = "I'm letter a" 
    func addLetters() -> String { 
     let newString = a + "bcdefg" 
     return newString 
    } 
    let moreLetters = addLetters() 
    return moreLetters 
} 

一个保留循环没有形成,因为没有一个甚至引用类型!没有要创建的对象。你在第二个代码中做的所有事情都是使用值类型的字符串。即使有班级,也不会形成保留周期,因为正如我所说的,当您将obj设置为nil时,由于方法属于对象,所以其中的所有方法“消失”。


什么那些我必须写[weak self]或保留循环形成封闭?

那些关闭是转义关闭。正常关闭后返回初始化。但是,转义闭包由某个对象保留,因此它们不会立即被初始化。欲了解更多信息,请参阅Escaping Closures in Swift

+0

非常感谢你 - 感谢我的问题,即使我忘记了一个简单的事实,即字符串是值类型,因此不会导致保留周期! – Jason210006

相关问题