Swift将未初始化的对象传递给阻止

时间:2015-06-13 08:20:19

标签: objective-c swift block

我一直试图找出这个用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实现类似的行为?

1 个答案:

答案 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)