我有一个简单的问题,我很难找到答案二。下面的代码崩溃。从调试看来,它似乎来自循环,我认为这是因为我在两个类中都引用了另一个类。有人可以解释发生了什么吗?如果可以,请说明我如何让两个班级互相交谈(双向)?任何帮助将不胜感激!谢谢。


  查看控制器一


import UIKit

class ViewControllerOne: UIViewController{

    let doSomething = DoSomething()
    var one = "test"

    @IBAction func buttonTapped(sender: AnyObject) {
        doSomething.functionTwo()
   }
}



  做这种崩溃


import UIKit

class DoSomething: NSObject {

    let viewControllerOne = ViewControllerOne()

    func functionTwo() -> String{
        var two = viewControllerOne.one
    return two
    }
}



  做某事


import UIKit

class DoSomething: NSObject {


    func functionTwo() -> String{
        let viewControllerOne = ViewControllerOne()

        var two = viewControllerOne.one
    return two
    }
}

最佳答案

首先,DoSomething的初始化程序必须创建一个ViewControllerOne。由于ViewControllerOne的初始化程序创建DoSomething,因此它们无限循环。
在第二个实例中,在调用DoSomething之前不会创建functionTwo(),因此没有循环。
例如,您可以让他们互相交谈:

import UIKit

class ViewControllerOne : UIViewController
{
    let doSomething = DoSomething()
    var one = "test"

    override func viewDidLoad()
    {
        super.viewDidLoad()
        doSomething.viewControllerOne = self
    }

    @IBAction func buttonTapped(sender: AnyObject)
    {
        doSomething.functionTwo()
    }
}

class DoSomething: NSObject
{
    weak var viewControllerOne : ViewControllerOne?

    func functionTwo() -> String
    {
        return viewControllerOne?.one ?? String()
    }
}


-

所以这是分步进行的:


创建ViewControllerOne后,将调用默认的初始化程序。
它为doSomething = DoSomething()和var one =“ test”(等于String(“ test”))调用初始化程序。
DoSomething默认的初始值设定项将可选的viewControllerOne设置为nil
当ViewControllerOne的实例加载完成时,将调用viewDidLoad。它将弱的doSomething.viewControllerOne属性设置为其自身。这意味着:

(用于ARC的)引用计数不会增加,这很重要,因为如果您决定删除ViewControllerOne的实例,而doSomething会对它进行强引用,则它们将永远不会被ARC删除,并且您将丢失内存
该属性引用的视图实例具有被称为-在Swift中名为self的viewDidLoad与其他语言中的this相似

调用functionTwo时,它要么返回one的值,要么如果viewControllerOne为nil,则返回一个空的String

10-04 17:57