2015-08-24 42 views
-5

这是Swift编程中以下场景中的内存泄漏吗?在Swift的下列情况下它是内存泄漏吗?

var string: String = "test-string-1" // statement-1 

string = "test-string-2" // statement-2 

是通过执行从语句-1到语句-2的内存泄漏吗?

或者我这样吗?

var string: String? = "test-string-1" 

string = nil 

string = "test-string-2" 

请用正确的描述来回答。

+3

什么让你想到会有泄漏?请先给我们一个正确的描述。 – holex

回答

2

你不需要在第二种方式。 我想第一个场景足够安全。

将字符串设置为"test-string-2"后,"test-string-1"的引用计数变为0.因此,它将被ARC解除分配。

1

你甚至不需要考虑这里的内存泄漏,这与将一个新值分配给一个变量非常不同。

class Parent { 
    var child:Child? 
} 

class Child { 
    var parent: Parent? 
} 

var child = Child() 
let parent = Parent() 

child.parent = parent 
parent.child = child // strong reference cycle created 

A“很强的参考周期”已被创建,因为母公司持有:当一个实例是不能被从内存中释放,并通过Apple in the docs的长度进行了说明,但在短暂这里是最简单的情况下它发生引用一个子实例,并且同一个子实例持有对拥有引用的父实例的引用。结果是无法确定何时取消任何实例的初始化。这可以通过将代码中的视图控制器和运行它的应用程序内来证明:

import UIKit 

class Parent { 
    var child:Child? 
    deinit { 
     print("deinitialized") 
    } 
} 

class Child { 
    var parent: Parent? 
    deinit { 
     print("deinitialized") 
    } 
} 
class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let child = Child() 
     let parent = Parent() 

     child.parent = parent 
     parent.child = child // strong reference cycle created 
    } 

} 

注意,没有控制台消息,以指示去初始化已经发生,因为它具有不。相反,这些实例都永远活得更多。我们称之为泄漏,因为这些实例并不存在,但同时它们不可访问。

现在改变其中一个引用到弱,像这样:

import UIKit 

class Parent { 
    var child:Child? 
    deinit { 
     print("deinitialized") 
    } 
} 

class Child { 
    weak var parent: Parent? 
    deinit { 
     print("deinitialized") 
    } 
} 
class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let child = Child() 
     let parent = Parent() 

     child.parent = parent 
     parent.child = child // strong reference cycle created 
    } 

} 

您将看到两个DEINIT消息。现在只有父母负责让孩子“活着”,因此它可以在孩子通过ARC自动离开时释放孩子。谁拥有谁,即使当一个拥有的实例提及它的所有者时,也没有含糊不清,因为它现在很弱(而不是强大)。