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

时间:2014-11-20 23:48:57

标签: ios objective-c swift lazy-loading

我正在尝试翻译一些基本上懒惰加载变量多次的Objective-C代码。代码类似于以下内容:

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

每当他们想要重建fetchedResultsController以使用新谓词时,他们只需将其设置为“nil”并调用它,它将使用新谓词重建它。

我正在努力在Swift中完成同样的任务。据我所知,Swift懒惰变量在第一次被调用后成为正常变量。这对我来说是个问题,因为如果我尝试将我的swift变量设置为nil并回想起来,它就不会重建但仍然是零。

将fetchedResultsController加载为惰性变量的工作代码如下所示。我已经尝试将它更改为计算属性,方法是添加一个检查它是否为nil并将其置于get块中,但这没有用。有什么想法吗?

    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
    }()

2 个答案:

答案 0 :(得分:22)

您可以使用由可选变量支持的计算属性创建类似于Objective-C方法的内容。

var _fetchedResultsController: NSFetchedResultsController?

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

答案 1 :(得分:6)

lazy只是实现了一个非常具体的memoization模式。它并不像你有时喜欢的那样神奇。您可以非常轻松地实现自己的模式以匹配您的ObjC代码。

只需创建一个包含实际值的第二个私有可选属性。创建一个标准(非惰性)计算属性,检查私有属性是否为nil,如果为零则更新它。

这与ObjC系统非常相似。在ObjC中,你有两个“事物”,一个叫_fetchedResultsController,另一个叫self.fetchedResultsController。在Swift中,你将有两件事,一件名为self.fetchedResultsController,另一件名为self._cachedFetchedResultsController(或其他)。