竞态条件与递归问题:字典未在执行下一行前返回
预期目标
- 以fixedValues作为dictionaryRepresentation参数初始化MyClass。
- 在执行init代码行前设置好修正后的值。
问题
- fixedValues在执行
self.init(...代码行前未完成设置。
已尝试的解决方案
- 使用返回值替代completion(当前状态)
- 利用completion、DispatchGroups、Notify
- 使用Semaphore等待值设置
信号量示例代码
class WaitForValue { private var semaphore = DispatchSemaphore(value: 0) var valueToWaitFor: String? { didSet { if valueToWaitFor != nil { semaphore.signal() } } } func waitForValue() { _ = semaphore.wait(timeout: .distantFuture) } } let waitForValueInstance = WaitForValue() // 会阻塞直到valueToWaitFor被设置为非nil值 DispatchQueue.global().async { waitForValueInstance.waitForValue() print("Value received: \(waitForValueInstance.valueToWaitFor ?? "nil")") } // 模拟延迟后设置值 DispatchQueue.global().asyncAfter(deadline: .now() + 2) { waitForValueInstance.valueToWaitFor = "Hello, World!" }
我的代码
class MyClass { convenience init?(_ object: Object) { guard let values = object.getValues(forKeys: MyAttributes.allAttributes) else { return nil } var fixedValues = values MyClass.correctedValues(object: object, values: values) { correctedValues in fixedValues = correctedValues } self.init(dictionary: fixedValues, type: object.type) } private static func correctedValues(object: Object, values: [String: Any], completion: @escaping([String: Any]) -> Void) { var valuesDictionary = values let fixes = objectFixes(object: object) let valueObjects = values["children"] as? [Object] ?? [] var wrappedObjects = [WrappedObject]() valueObjects.forEach { let wrapped = WrappedObject($0) wrappedObjects.append(wrapped) } fixedChildrenValues(originalValues: wrappedObjects, fixes: fixes) { correctedChildren in valuesDictionary["children"] = correctedChildren completion(valuesDictionary) } } private static func fixedChildrenValues(originalValues: [WrappedObject], fixes: [String: [Attribute: String]], completion: @escaping ([[String: Any]]) -> Void) { var fixedChildrenArray = [[String: Any]]() for childValue in originalValues { var childAttributes = childValue.getValues(forKeys: [ "children", "identifier", "props", "name" ]) ?? [:] // 应用修正 if let matchingIdentifier = childAttributes["identifier"] as? String, let fix = fixes[matchingIdentifier] { fix.forEach { (key, value) in childAttributes[key] = value } } // 尝试提取子元素并继续遍历 if let childrenObjects = childAttributes["children"] as? [Object] { var wrappedObjects = [WrappedObject]() for childObject in childrenObjects { wrappedObjects.append(WrappedObject(childObject)) } if !wrappedObjects.isEmpty { fixedChildrenValues(originalValues: wrappedObjects, fixes: fixes) { correctedChildren in childAttributes["children"] = correctedChildren fixedChildrenArray.append(childAttributes) } } else { fixedChildrenArray.append(childAttributes) } } else { fixedChildrenArray.append(childAttributes) } } completion(fixedChildrenArray) } private static func objectFixes(object: Object) -> [String: [Attribute: String]] { var objectFixes = [String: [Attribute: String]]() let objects = object.objects for i in 0..<objects.count { let obj = objects[i] if !obj.isEnabled { objectFixes[obj.identifier] = ["props": "false"] } } return objectFixes } }
内容的提问来源于stack exchange,提问作者Tristan Newman
相关产品推荐
相关产品推荐

