我一直试图找出这个用Objective C很容易的小东西,但用Swift无法解决。
var loginViewController: SSLoginViewController
let completion = {
loginViewController.presentViewController(SSFeedViewController(), animated: true, completion: nil)
}
loginViewController = SSLoginViewController(completion: completion)
这里的目的是通过SSLoginViewController一个completionBlock来呈现另一个视图控制器。但是,上面的代码给出了错误。
变量'loginViewController'在关闭之前被闭包捕获 初始化。
将未初始化的变量显示为 __ block ,Objective C块将从块中获取更改的值。
在Objective C中会是这样的,
__block SSLoginViewController *loginViewController;
dispatch_block_t completion = ^ {
[loginViewController presentViewController:[[SSFeedViewController alloc] init] animated: YES completion:nil]
};
loginViewController = [[SSLoginViewController alloc] initWithCompletion:completion];
如何使用Swift实现类似的行为?
答案 0 :(得分:0)
它应该初始化为nil
(这就是你的Objective-C代码中发生的事情;在Objective-C ARC中,如果没有初始化,托管对象指针被初始化为nil
。这意味着它需要是可选的。您可以使用隐式解包的可选项来处理可选语法,因为您知道它只是临时的nil
。
var loginViewController: SSLoginViewController!
let completion = {
loginViewController.presentViewController(SSFeedViewController(), animated: true, completion: nil)
}
loginViewController = SSLoginViewController(completion: completion)
您的Objective-C代码中也存在的另一个问题是可能存在保留周期。 SSLoginViewController
对象可能存储并因此具有对完成块的强引用,并且该块具有对SSLoginViewController
对象的强引用。如果您知道完成块仅在SSLoginViewController
对象处于活动状态时存在,那么您可以让它捕获对loginViewController
的弱引用:
var loginViewController: SSLoginViewController!
let completion = { [weak loginViewController] in
loginViewController.presentViewController(SSFeedViewController(), animated: true, completion: nil)
}
loginViewController = SSLoginViewController(completion: completion)