【问题标题】:Swift - Lazy loading a property that can be made nil laterSwift - 延迟加载稍后可以设为 nil 的属性
【发布时间】:2014-11-15 04:37:23
【问题描述】:

我正在寻找一种方法来延迟加载我的变量,但我希望能够稍后将其设为 nil,然后在获取时重新创建它。例如,在出现内存警告的情况下,我想清除任何未使用的内容,然后在以后需要时重新创建它。

以下是我在 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;
    }
}

【问题讨论】:

    标签: properties swift loading lazy-evaluation


    【解决方案1】:

    您缺少的部分是,在 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 的值都是程序员错误,并且由此产生的崩溃是适当的。

    【讨论】:

    • 啊,好吧,我不确定我是否在 ivar 的命名中遗漏了一些东西,或者它现在是否完全消失了。除非您有与我类似的情况,否则这似乎是您通常不会迅速做的事情。感谢您提供的所有信息,非常感谢!
    • 我实际上经常使用这种模式,只是它在 Swift 中没有那么自动化。不久前,当自动属性合成器还没有出现时,你必须在 Obj-C 中做同样的事情:)
    猜你喜欢
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多