在AppDelegate中使用强委托用于初始ViewController

时间:2017-01-05 02:49:07

标签: ios swift delegates automatic-ref-counting

我的初始GameViewController的委托属性为GameDelegate。我在AppDelegate

中设置了此属性
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    //Set initial view controller
    window = UIWindow(frame: UIScreen.main.bounds)
    if let window = window {
        let gameTracker = GameTracker()
        let gameViewController = GameViewController()
        gameViewController.delegate = gameTracker
        window.rootViewController = gameViewController
        window.makeKeyAndVisible()
    }
    return true
}

这只有在我的代表很强的情况下才有效:

class GameViewController: UIViewController{

        var delegate: GameDelegate?

        var gameScore: GameScore {
            return (delegate!.gameScore)
        }

        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }

使用弱委托将导致应用程序崩溃,因为在GameViewController出现后委托将为零。

我的问题是:这种方法是否安全,如果不安全,应该怎样做?我已经阅读了有关代表的内容,并建议将其保留为弱变量以防止保留周期。我没有使用故事板。

2 个答案:

答案 0 :(得分:2)

问题是你在函数中声明gameTracker,而不是作为类级变量。当函数退出时,AppDelegate对它的引用会立即释放,只留下GameViewController对它的引用。

解决此问题的方法是在gameTracker中将AppDelegate声明为类级变量:

var gameTracker: GameTracker?

您需要将其声明为可选项,因为您只想在满足if条件时对其进行实例化:

if let window = window {
    self.gameTracker = GameTracker()
    let gameViewController = GameViewController()
    gameViewController.delegate = self.gameTracker
    window.rootViewController = gameViewController
    window.makeKeyAndVisible()
}

如果您执行此操作,则可以在delegate中将weak声明为GameViewController

答案 1 :(得分:1)

安全方法是使用弱委托。如果你处理零,那么它不应该是一个问题。

weak var delegate: GameDelegate?

var gameScore: GameScore? {
    return delegate?.gameScore
}

您是否打算致电'委托'当游戏分数为'变化?如果你想保存游戏分数'以及返回' delegate'那么你应该使用属性观察者。

var gameScore: GameScore {
    didSet {
        delegate?.gameScore
    }
}