简体   繁体   English

加载多次的Swift Lazy变量(计算属性?)

[英]Swift Lazy Variables that Load more than Once (Computed Properties?)

I'm trying to translate some Objective-C code that was essentially lazy loading a variable multiple times. 我正在尝试翻译一些基本上懒惰加载变量的Objective-C代码。 The code was similar to the following: 代码类似于以下内容:

-(NSFetchedResultsController *)fetchedResultsController {
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }
    //...code to build the fetchedResultsController with a new predicate

Whenever they wanted to rebuild the fetchedResultsController to use a new predicate, they would just set it to "nil" and call it, and it would rebuild it with a new predicate. 每当他们想重建fetchedResultsController以使用新的谓词时,他们只需将其设置为“nil”并调用它,它将使用新的谓词重建它。

I'm struggling to do this same task in Swift. 我正在努力在Swift中完成同样的任务。 As far as I can tell, Swift lazy variables become normal variables after they are called for the first time. 据我所知,Swift懒惰变量在第一次被调用后成为正常变量。 This is causing issues for me because if I try to set my swift variable back to nil, and recall it, it doesn't rebuild but remains nil. 这对我来说是个问题,因为如果我尝试将我的swift变量设置为nil并回想起来,它就不会重建但仍然是零。

The working code to load my fetchedResultsController as a lazy varaible is below. 将fetchedResultsController加载为惰性变量的工作代码如下所示。 I've tried changing it to a computed property by adding a check if its nil and have it within a get block, but that hasn't worked. 我已经尝试将它更改为计算属性,方法是添加一个检查它是否为nil并将其置于get块中,但这没有用。 Any ideas? 有任何想法吗?

    lazy var taskController : NSFetchedResultsController? = {
        var subtaskRequest = NSFetchRequest(entityName: "Subtasks")
        var segIndex = self.segmentedControl.selectedSegmentIndex
        subtaskRequest.predicate = NSPredicate(format: "task.category.name == %@", self.segmentedControl.titleForSegmentAtIndex(segIndex)!)
        subtaskRequest.sortDescriptors = [NSSortDescriptor(key: "task.englishTitle", ascending: true), NSSortDescriptor(key: "sortOrder", ascending: true)]


        let controller = NSFetchedResultsController(fetchRequest: subtaskRequest, managedObjectContext:
            self.managedObjectContext!, sectionNameKeyPath: "task.englishTitle", cacheName: nil)
        controller.delegate = self
        return controller
    }()

You can create something similar to the Objective-C method using a computed property backed by an optional variable. 您可以使用由可选变量支持的计算属性创建类似于Objective-C方法的内容。

var _fetchedResultsController: NSFetchedResultsController?

var fetchedResultsController: NSFetchedResultsController {
    get {
        if _fetchedResultsController != nil {
            return _fetchedResultsController!
        }
        //create the fetched results controller...
        return _fetchedResultsController!
    }
}

lazy just implements a very specific memoization pattern. lazy只是实现一个非常具体的memoization模式。 It's not as magical as you'd sometimes like it to be. 它并不像你有时喜欢的那样神奇。 You can implement your own pattern to match your ObjC code pretty easily. 您可以非常轻松地实现自己的模式以匹配您的ObjC代码。

Just make a second private optional property that holds the real value. 只需创建一个包含实际值的第二个私有可选属性。 Make a standard (non-lazy) computed property that checks the private property for nil and updates it if it's nil. 创建一个标准(非惰性)计算属性,检查私有属性是否为nil,如果为零,则更新它。

This is pretty much identical to the ObjC system. 这与ObjC系统非常相似。 In ObjC you had two "things," one called _fetchedResultsController and the other called self.fetchedResultsController . 在ObjC中,你有两个“东西”,一个叫做_fetchedResultsController ,另一个叫做self.fetchedResultsController In Swift you'll have two things, one called self.fetchedResultsController and the other called self._cachedFetchedResultsController (or whatever). 在Swift中你将有两件事,一件名为self.fetchedResultsController ,另一件名为self._cachedFetchedResultsController (或其他)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM