swift中的NSMutableDictionary.lazy是什么意思?
What is meaning of NSMutableDictionary.lazy in swift?
我对在哪里使用 lazy 功能感到困惑,我的意思是说我应该在哪种类型的条件下使用 lazy 关键字集合。
lazy 的工作方式是初始化程序(或 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")
惰性求值 是指将表达式的求值推迟到需要结果时。这与 eager evaluation 形成对比,后者是立即完成表达式的计算。
考虑这个表达式:
let input = [1, 2, 3]
let evens = input.map{ [=10=] * 2 }
每个数字 (1, 2, 3) 都通过闭包 { [=13=] * 2 }
映射到一个新值,闭包将它们乘以 2。这个评估是急切完成的。也就是说,执行此行的时刻是执行 map
函数的计算,计算结果存储在 evens
中。 input
是 Array<Int>
类型,结果 evens
也是 Array<Int>
.
类型
现在考虑这个表达式:
let input = [1, 2, 3]
let evens = input.lazy.map{ [=11=] * 2 }
每个数字 (1, 2, 3) 将 通过闭包 { [=13=] * 2 }
成为一个新值,将它们乘以 2。但是,这评估是懒惰的。也就是说,在执行这一行的那一刻,乘法还没有完成。相反,闭包 { [=13=] * 2 }
被存储以供将来参考。 input
是 Array<Int>
类型,结果 evens
也是 LazyMapRandomAccessCollection<Array<Int>, Int>
类型。乘法被推迟到元素被访问。如果一个元素从未被访问过,那么它就不会被处理。
在这种微不足道的情况下,为将来的评估存储闭包的簿记开销会比仅仅急切地计算结果要大。但是,你可以设想这样的情况:
let input = 1...1000000000
let evens = input.lazy.map{ [=12=] * 2 }
print(evens[0])
在序列中的所有 1000000000
中,只有一个被使用过。评估闭包 1000000000
次,产生 1000000000
结果,将它们全部存储在内存中确实效率低下,如果只需要第一个元素的话。
lazy
是Sequence
协议的一个实例方法。所有符合的类型,包括 NSMutableDictionary
都实现它。它们都做同样的事情:它们将 map
和 filter
语句中的元素的处理推迟到需要它们的结果的时候。这可以在元素很多且只需要其中一小部分的情况下节省内存和处理时间。
来自 Apple 文档:
A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.
当使用 @lazy
属性 然后记住以下事情:
- Lazy 属性 必须始终使用
var
关键字声明,而不是使用 let
常量。
- 惰性属性必须在声明时初始化。
我们如何在 Objective-C
中实现惰性功能
@property (nonatomic, strong) NSMutableArray *players;
- (NSMutableArray *)players
{
if (!_players) {
_players = [[NSMutableArray alloc] init];
}
return _players;
}
现在在 Swift 中,您可以使用 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
但是当您尝试打印个性化问候语时,它是即时计算的:
print(person.personalizedGreeting)
// personalizedGreeting is calculated when used
// and now contains the value "Hello, John Doe!"
我希望这能帮助您理解 lazy 属性 的功能。
我对在哪里使用 lazy 功能感到困惑,我的意思是说我应该在哪种类型的条件下使用 lazy 关键字集合。
lazy 的工作方式是初始化程序(或 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")
惰性求值 是指将表达式的求值推迟到需要结果时。这与 eager evaluation 形成对比,后者是立即完成表达式的计算。
考虑这个表达式:
let input = [1, 2, 3]
let evens = input.map{ [=10=] * 2 }
每个数字 (1, 2, 3) 都通过闭包 { [=13=] * 2 }
映射到一个新值,闭包将它们乘以 2。这个评估是急切完成的。也就是说,执行此行的时刻是执行 map
函数的计算,计算结果存储在 evens
中。 input
是 Array<Int>
类型,结果 evens
也是 Array<Int>
.
现在考虑这个表达式:
let input = [1, 2, 3]
let evens = input.lazy.map{ [=11=] * 2 }
每个数字 (1, 2, 3) 将 通过闭包 { [=13=] * 2 }
成为一个新值,将它们乘以 2。但是,这评估是懒惰的。也就是说,在执行这一行的那一刻,乘法还没有完成。相反,闭包 { [=13=] * 2 }
被存储以供将来参考。 input
是 Array<Int>
类型,结果 evens
也是 LazyMapRandomAccessCollection<Array<Int>, Int>
类型。乘法被推迟到元素被访问。如果一个元素从未被访问过,那么它就不会被处理。
在这种微不足道的情况下,为将来的评估存储闭包的簿记开销会比仅仅急切地计算结果要大。但是,你可以设想这样的情况:
let input = 1...1000000000
let evens = input.lazy.map{ [=12=] * 2 }
print(evens[0])
在序列中的所有 1000000000
中,只有一个被使用过。评估闭包 1000000000
次,产生 1000000000
结果,将它们全部存储在内存中确实效率低下,如果只需要第一个元素的话。
lazy
是Sequence
协议的一个实例方法。所有符合的类型,包括 NSMutableDictionary
都实现它。它们都做同样的事情:它们将 map
和 filter
语句中的元素的处理推迟到需要它们的结果的时候。这可以在元素很多且只需要其中一小部分的情况下节省内存和处理时间。
来自 Apple 文档:
A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.
当使用 @lazy
属性 然后记住以下事情:
- Lazy 属性 必须始终使用
var
关键字声明,而不是使用let
常量。 - 惰性属性必须在声明时初始化。
我们如何在 Objective-C
中实现惰性功能@property (nonatomic, strong) NSMutableArray *players;
- (NSMutableArray *)players
{
if (!_players) {
_players = [[NSMutableArray alloc] init];
}
return _players;
}
现在在 Swift 中,您可以使用 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
但是当您尝试打印个性化问候语时,它是即时计算的:
print(person.personalizedGreeting)
// personalizedGreeting is calculated when used
// and now contains the value "Hello, John Doe!"
我希望这能帮助您理解 lazy 属性 的功能。