Swift-延迟加载一个可以在以后设置为零的属性 [英] Swift - Lazy loading a property that can be made nil later

查看:40
本文介绍了Swift-延迟加载一个可以在以后设置为零的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种延迟加载变量的方法,但是我希望以后可以将其设置为nil,然后在get上重新创建它.例如,在出现内存警告的情况下,我想清除所有未使用的内容,然后在以后需要时重新创建.

I am looking for a way to lazy load my variable, but I want to be able to make it nil later and then recreate it on the get. For example in the instance that there is a memory warning i want to clear anything that isn't used and then recreate it when needed again later.

这就是我在Objective-C中的处理方式以及我目前的快速解释.我不确定是否保留用于保持当前导航的变量.

Here is how I would do it in Objective-C and my current interpretation in swift. I am not sure that it preserves the variable for keeping current navigation.

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中,您需要自己创建那些.

The piece that you're missing is that, in Objective-C, it's creating the _navController ivar and setter for you; in Swfit you need to create those yourself.

一旦有了这些属性,您在Swift中的navController属性就会看起来与Objective-C相似:

Once you have those in place, your navController property in Swift can look pretty similar to the Objective-C one:

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,同时仍可访问它而无需每次都解开该值.虽然使用隐式展开类型可能很危险,但在这种情况下可以使用(并且适当).由于我们在吸气剂中检查nil,因此我们可以保证它将始终返回非nil值.此外,即使我们对instantiateInitialViewController返回的值使用条件下调,也可以说该函数返回的任何不是 UINavigationController值都将是程序员错误,并且导致的崩溃将是适当的.

Note: I delcared navController as an implicitly unwrapped UINavigationController so that it can be set to nil while still making it accessible without unwrapping the value every time. While using an implicitly unwrapped type can be dangerous, it's ok (and appropriate) to use in this case. Since we check for nil in the getter itself, we can guarantee that it will always return a non-nil value. Additionally, even though we're using a conditional downcast on the value returned from instantiateInitialViewController, we can say that any value returned from that function that is not a UINavigationController would be a programmer error and the resulting crash would be appropriate.

这篇关于Swift-延迟加载一个可以在以后设置为零的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆