swift中的NSMutableDictionary.lazy的含义是什么?

问题描述:

我很困惑在哪里使用懒惰功能,我的意思是说我应该在哪种类型的条件下使用懒惰关键字在集合中。swift中的NSMutableDictionary.lazy的含义是什么?

+0

接受的答案与“NSMutableDictionary.lazy”无关......属性的“lazy”关键字完全不同。 – Alexander

从苹果文档:

懒惰存储属性是一个属性,其初始值是不计算使用它的第一次直到。通过在声明之前编写lazy修饰符来指示惰性存储属性。

使用时@lazy财产然后记住以下事情:

  • 懒惰的属性必须始终与var关键字声明,不与let不变。
  • 惰性属性在声明时必须初始化。

我们如何在Objective-C

@property (nonatomic, strong) NSMutableArray *players; 

- (NSMutableArray *)players 
{ 
    if (!_players) { 
     _players = [[NSMutableArray alloc] init]; 
    } 
    return _players; 
} 

实现懒的功能现在在斯威夫特,您可以通过使用lazy属性实现同样的功能。见下面的例子

class Person { 

    var name: String 

    lazy var personalizedGreeting: String = { 

     return "Hello, \(self.name)!" 
    }() 

    init(name: String) { 
     self.name = name 
    } 
} 

现在,当你初始化一个人,他们的个人问候语尚未创建:

let person = Person(name: "John Doe") // person.personalizedGreeting is nil 

但是当你试图打印出个性化的问候语,它是计算上的-fly:

print(person.personalizedGreeting) 
// personalizedGreeting is calculated when used 
// and now contains the value "Hello, John Doe!" 

我希望这能帮助你理解懒惰属性的功能。

+0

这与'NSMutableDictionary.lazy'无关。 – Alexander

懒惰的工作方式是初始化程序(或init方法)只在第一次访问变量或属性时才运行。我看到了一个主要原因,为什么它在你的代码中不起作用(至少是直接),那是因为你将两个懒惰的实例化代码打包到了一个方法中(loadEntriesIfNeeded)。

要使用惰性实例化,您可能需要扩展NSMutableArray和NSDictionary,并为您的惰性实例化重写或创建自定义初始化程序。然后,将loadEntriesIfNeeded中的代码分发到它们各自的初始值设定项中。

import Swift 

println("begin") 

class ClassWithLazyProperties { 

    lazy var entries:[String] = ClassWithLazyProperties.loadStuff() 
    lazy var entriesByNumber:Dictionary<Int, String> = { 

     var d = Dictionary<Int, String>() 
     for i in 0..<self.entries.count { 
      d[i] = self.entries[i] 
     } 
     return d 
    }() 

    private class func loadStuff() -> [String] { 
     return ["Acai", "Apples", "Apricots", "Avocado", "Ackee", "Bananas", "Bilberries"] 
    } 

} 

let c = ClassWithLazyProperties() 
c.entriesByNumber 
    // 0: "Acai", 1: "Apples", 2: "Apricots", 3: "Avocado", 4: "Ackee", 5: "Bananas", 6: "Bilberries"] 


println("end") 
+0

这个问题与'lazy var's无关。另外,你应该避免在'self.entries.indices'中写''in 0 .. Alexander

惰性求是当表达式的评估被延迟,直到所需要的结果。这与渴望评估形成对比,这是对表达式的评估立即完成的时候。

考虑以下表达式:

let input = [1, 2, 3] 
let evens = input.map{ $0 * 2 } 

号码的每个数字(1,2,3)由闭合{ $0 * 2 },其通过2.该评价急切地完成它们相乘映射到一个新的值。也就是说,执行该行的时刻是执行map函数的评估,并且计算结果存储在evens中。 input类型为Array<Int>,结果evens也是Array<Int>类型。

现在考虑以下表达式:

let input = [1, 2, 3] 
let evens = input.lazy.map{ $0 * 2 } 

号码的每个数字(1,2,3)将由闭合{ $0 * 2 },其通过2.它们相乘然而是为一个新值,该评价是懒惰地完成的。也就是说,在这一行正在执行的时候,乘法没有完成。相反,关闭{ $0 * 2 }存储供将来参考。 input类型为Array<Int>,结果evens也是LazyMapRandomAccessCollection<Array<Int>, Int>类型。乘法推迟到元素为访问。如果一个元素永远不会被访问,那么它就不会被处理。

在这样一个微不足道的情况下,存储闭包用于未来评估的簿记开销将大于只是急切地计算结果。但是,你可以设想这样的情况:

let input = 1...1000000000 
let evens = input.lazy.map{ $0 * 2 } 
print(evens[0]) 

所有序列中的1000000000中,只有一个被使用过。评估关闭1000000000次,以产生1000000000结果,如果只有第一个元素将被需要,将它们全部存储在内存中实际上是低效的。

lazySequence协议的实例方法。所有符合的类型,包括NSMutableDictionary都执行它。它们都做同样的事情:它们推迟处理mapfilter语句中的元素,直到需要结果为止。这可以节省内存和处理时间,在有很多元素的情况下,只需要其中的一小部分。