我正在寻找一种延迟加载变量的方法,但我希望稍后能够使其为零,然后在get上重新创建它。例如,在出现内存警告的情况下,我想清除任何未使用的内容,然后在需要时重新创建。
以下是我在Objective-C中如何做到这一点,以及我目前在swift中的解释。我不确定它是否保留了保持当前导航的变量。
Obj-C实现
@property (strong, nonatomic, readwrite) UINavigationController *navController;
...
- (UINavigationController *)navController {
if (!_navController) {
UIStoryboard *tempStoryboard = [UIStoryboard storyboardWithName:@"SomeStoryboard" bundle:nil];
_navController = [tempStoryboard instantiateInitialViewController];
}
return _navController;
}
...
- (void)didReceiveMemoryWarning
{
if (![self.centerView isEqual:_navController]) {
_navController = nil;
}
}
快速实现
var navController :UINavigationController? {
get {
// There is no assignment to the a variable and I can't check if the current value is nil or it recalls the get method and hence re-create it if it is nil.
let tempStoryboard = UIStoryboard(name: "Image", bundle: nil);
let tempNavController: AnyObject = tempStoryboard.instantiateInitialViewController();
return tempNavController as? UINavigationController;
}
}
...
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
if (!self.centerPanel.isEqual(navController)) {
self.navController = nil;
}
}
您缺少的是,在Objective-C中,它正在为您创建_navController
ivar和setter;在Swfit中,您需要自己创建这些。
一旦你有了这些,你在Swift中的navController
属性可以看起来非常类似于Objective-C属性:
private var _navController: UINavigationController? = nil
var navController: UINavigationController! {
get {
if _navController == nil {
let tempStoryboard = UIStoryboard(name: "Image", bundle: nil);
_navController = tempStoryboard.instantiateInitialViewController() as? UINavigationController
}
return _navController
}
set {
_navController = newValue
}
}
注意:我将navController
建模为隐式展开的UINavigationController
,这样它就可以设置为nil
,同时仍然可以访问它,而无需每次都展开值。虽然使用隐式展开的类型可能很危险,但在这种情况下使用它是可以的(也是合适的)。由于我们在getter本身中检查nil
,我们可以保证它总是返回一个非nil
的值。此外,即使我们对instantiateInitialViewController
返回的值使用了条件下转换,我们也可以说,从该函数返回的任何而不是UINavigationController
的值都将是程序员错误,由此导致的崩溃将是适当的。