作者:HS_G_960 | 来源:互联网 | 2023-02-05 20:27
1> Rob..:
你说:
该stateQueue
物业的目的是什么?我看到它被get和set的state
计算属性使用,但我找不到任何解释它们sync:flags:execute
和sync:execute
它们使用的方法的文档.
此代码"同步"对属性的访问以使其线程安全.至于为什么你需要做的是,看到的Operation
文件,其中建议:
多核注意事项
...当您进行子类化时NSOperation
,必须确保从多个线程调用任何重写的方法都是安全的.如果在子类中实现自定义方法(如自定义数据访问器),则还必须确保这些方法是线程安全的.因此,必须同步对操作中的任何数据变量的访问,以防止潜在的数据损坏.有关同步的更多信息,请参阅" 线程编程指南".
关于这个并发队列用于同步的确切用法,这被称为"读写器"模式.读写器模式的这个基本概念是读取可以相互发生并发生(因此sync
,没有障碍),但是对于该属性的任何其他访问(因此async
具有障碍),写入决不能同时执行.这些都在WWDC 2012视频异步设计模式与块,GCD和XPC中描述.请注意,而视频概述基本的概念,它使用旧的Operation
和NSObject
语法,而不是仅仅的斯威夫特3及更高版本的语法["state"]
和NSObject
这里使用的语法.
你还问:
class func keyPathsForValuesAffectingValue(forKey key: String) -> Set
返回部分中三个类方法的目的是什么state
?我没有看到它们被用在任何地方.我找到了isReady
,isExecuting
但是,这似乎没有帮助我理解为什么声明这些方法.
这些只是确保对isFinished
属性的更改触发属性的KVN的方法keyPathsForValuesAffectingValue
,AsynchronousOperation
以及super.start()
.这三个密钥的KVN对于异步操作的正确运行至关重要.无论如何,在键值观察编程指南:注册从属密钥中概述了这种语法.
start
您找到的方法是相关的.您可以使用该方法注册相关密钥,也可以使用原始代码段中显示的各个方法.
顺便说一句,这是super
您提供的课程的修订版,即:
你不能打电话@objc
.正如execute
文档所述(强调添加):
如果要实现并发操作,则必须覆盖此方法并使用它来启动操作.您的自定义实现不得main
随时调用.
Operation
在Swift 4中添加所需.
重命名isReady
为use final
,这是isReady
子类的约定.
宣布#keyPath
为dynamic
财产是不恰当的.任何子类都应该有权进一步完善其willChangeValue
逻辑(尽管我们很少这样做).
使用didChangeValue
使代码更安全/健壮.
使用finish
属性时,您不需要手动KVN .本例中手动调用.finished
和stateQueue
不需要.
改变,state
以便它只移动到sync:flags:execute
状态if sync:execute
.
从而:
class ThreadSafeArray {
private var values: [T]
private let queue = DispatchQueue(label: "...", attributes: .concurrent)
init(_ values: [T]) {
self.values = values
}
func reader(block: () throws -> U) rethrows -> U {
return try queue.sync {
try block()
}
}
func writer(block: @escaping (inout [T]) -> Void) {
queue.async(flags: .barrier) {
block(&self.values)
}
}
// e.g. you might use `reader` and `writer` like the following:
subscript(_ index: Int) -> T {
get { reader { values[index] } }
set { writer { $0[index] = newValue } }
}
func append(_ value: T) {
writer { $0.append(value) }
}
func remove(at index: Int) {
writer { $0.remove(at: index)}
}
}
我不同意.[并发编程指南](https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW16)鼓励使用`start`和`main`进行异步操作.在讨论`main`和异步操作时,他们说,"虽然你可以在`start`方法中执行任务,但使用[`main`]实现任务可以使你的设置和任务代码更清晰地分离. ".