swift中的NSMutableDictionary.lazy的含义是什么?
从苹果文档:
懒惰存储属性是一个属性,其初始值是不计算使用它的第一次直到。通过在声明之前编写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!"
我希望这能帮助你理解懒惰属性的功能。
这与'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")
这个问题与'lazy var's无关。另外,你应该避免在'self.entries.indices'中写''in 0 ..
惰性求是当表达式的评估被延迟,直到所需要的结果。这与渴望评估形成对比,这是对表达式的评估立即完成的时候。
考虑以下表达式:
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
结果,如果只有第一个元素将被需要,将它们全部存储在内存中实际上是低效的。
lazy
是Sequence
协议的实例方法。所有符合的类型,包括NSMutableDictionary
都执行它。它们都做同样的事情:它们推迟处理map
和filter
语句中的元素,直到需要结果为止。这可以节省内存和处理时间,在有很多元素的情况下,只需要其中的一小部分。
接受的答案与“NSMutableDictionary.lazy”无关......属性的“lazy”关键字完全不同。 – Alexander