- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有 Set<CostumObject>
类型的实例我想使用 NSKeyedArchiver
存档.
假设customObject1: CostumObject
和 customObject2: CostumObject
在某处实例化。
如果我使用下面的语句:
let setOfCostomObjects: Set<CostumObject> = [customObject1, customObject2]
let data = NSKeyedArchiver.archivedData(withRootObject: setOfCostomObjects)
NSKeyedArchiver
按顺序归档两个自定义对象,其中递归地归档它们的属性。
这不是线程安全的,因为另一个线程可以在归档期间改变自定义对象及其属性。
我认为我可以线程安全地归档自定义对象的每个属性,以便允许并发获取但只允许一个集合,方法是使用一个带有 set 屏障的并发队列,例如:
private let concurrentPropertyAccessQueue = DispatchQueue(label: "concurrentPropertyAccessQueue", attributes: .concurrent)
…
private var safeProperty = CostumProperty.init()
public private(set) var property: CostumProperty {
get {
var result = CostumProperty.init()
concurrentPropertyAccessQueue.sync { result = safeProperty } // sync, because result is returned
return result
} // get
set { concurrentPropertyAccessQueue.async(flags: .barrier) { safeProperty = newValue } // executes locked after all gets
} // set
}
…
public func threadSafeArchiveOfProperty() -> Data {
var data = Data.init()
concurrentPropertyAccessQueue.sync { // sync, because result is returned
data = NSKeyedArchiver.archivedData(withRootObject: self.safeProperty)
}
return data
}
我想我也可以用类似的方式对整个自定义对象进行线程安全归档:
private let concurrentObjectAccessQueue = DispatchQueue(label: "concurrentObjectAccessQueue", attributes: .concurrent)
…
public func encode(with aCoder: NSCoder) {
concurrentObjectAccessQueue.async(execute: {
aCoder.encode(self.property forKey: "property")
…
})
}
问题仍然是,如何线程安全地归档自定义对象集。
这将要求在归档期间锁定对集合元素的写访问。
这样做的一种方法可能是定义一个全局并发队列:
public let globalConcurrentAccessQueue = DispatchQueue(label: "globalConcurrentAccessQueue", attributes: .concurrent)
要在归档期间锁定集合及其所有元素,可能需要对 Set
进行扩展。定义 func threadSafeArchiveOfSet()
的类型如上。
然后这个函数将覆盖 Set 的 encode(with aCoder: NSCoder)
,所以 globalConcurrentAccessQueue
被锁住了。
这是正确的方法吗?
我认为这是一个应该有标准解决方案的标准问题。
最佳答案
通常,属性级同步是不够的。它提供对单个属性的线程安全访问,但不能确保对更广泛的对象的线程安全访问,因为不同属性之间可能存在相互依赖关系。原型(prototype)示例是一个具有名字和姓氏属性的 Person
对象。分别对名字和姓氏进行同步更改仍可能导致以内部不一致状态捕获的对象。您经常需要在更高级别同步对象,如果您这样做,它会使属性级同步变得冗余。
一些不相关的观察:
encode
方法必须同步执行其任务,而不是异步执行。调用者假定编码在返回时已完成。我可以猜到你为什么让它异步(例如,毕竟它没有显式返回任何东西),但问题不是是否返回任何东西,而是更广泛地说,是否有任何副作用同步对象。在这种情况下有(你正在更新 NSCoder
对象),所以你必须在 encode
中使用 sync
。
有几次您采用了初始化变量的模式,调用 sync
来修改该局部变量,然后返回该值。例如
func threadSafeArchiveOfProperty() -> Data {
var data = Data.init()
concurrentPropertyAccessQueue.sync { // sync, because result is returned
data = NSKeyedArchiver.archivedData(withRootObject: self.safeProperty)
}
return data
}
但是 sync
提供了一个很好的方法来简化这个,即如果闭包返回一个值,sync
也会返回它。如果闭包只有一行,您甚至不需要在闭包中显式 return
:
func threadSafeArchiveOfProperty() -> Data {
return concurrentPropertyAccessQueue.sync { // sync, because result is returned
NSKeyedArchiver.archivedData(withRootObject: self.safeProperty)
}
}
关于swift - 如何线程安全地归档一组自定义对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48034424/
我正在阅读许多 plist 并将它们显示在 UITableview 中。问题是,应用程序本身非常慢,我确实阅读了一些有关归档或序列化的内容,归档是否会使应用程序更快,或者如果我想使用大量数据,我应该尝
我用谷歌搜索并搜索了 SO,但没有直接的结果。看来我对 Apple 文档中的以下内容存在根本性的误解: An archive can store an arbitrarily complex obje
刚开始学习 iOS,我有一个非常基本的问题:归档/取消归档整个对象集合的正确方法是什么? 我了解到您首先需要在类上实现 NSCoder 协议(protocol)。假设我有一个可以正确归档和取消归档的类
所以这是我的问题。我正在尝试归档一个对象数组,当我取消归档它们时,尽管计数相同并且根对象内的对象相同,但它在未归档的数组中找不到指定的对象。 -(void)tableView:(UITableView
我需要归档一个由 ArrayController 控制的 NSMutableArray。我试过这个: [NSKeyedArchiver archivedDataWithRootObject:array
我想存档只包含 NSString 的字典,但是当我取消存档时,发生错误: [NSKeyedUnarchiver initForReadingWithData:]: non-keyed archive
我想存档每个构建的构建日志,例如到数据库。我知道如何归档工件,但我没有在构建日志中看到任何明显的内容。 最佳答案 我想您需要在归档之前结束您的工作。以下是一个 Groovy 脚本,它使用不同的方法来获
因此,我正在尝试将我的 iPhone 应用程序存档以进行临时测试,但我遇到了一些奇怪的情况。当我归档它时,在它显示归档类型的顶部,由于某种原因,它显示“Mac 应用程序归档”而不是通常的“iOS 应用
我正在使用 java Spring 和 spring data for mongodb。 我有一个集合,需要仅包含过去 3 个月的文档,但所有文档都应以某种方式保存(也许导出到文件?)。我正在寻找解决
我的应用程序使用了一个我插入的附加项目,我链接它然后使用以下代码导入它: #import 如果我正常运行应用程序,应用程序工作正常,但如果我按下存档按钮,上面报告的代码行就会出错。它说:找不到 SB
我有多个表。如表 1、表 2、表 3 等 需要什么: 1. 从表 1 中获取特定行。 (例如:id = 203) 2. 从 table2 中获取与 id 203 相关的所有值(例如:1,2,3,4,5
我正在尝试使用 Xcode 4.3.2 将我的应用存档到一个 .ipa 文件中以发送到应用商店,但在尝试存档时出现此错误: 'KKGridView/KKGridView.h' file not fou
这个问题在这里已经有了答案: Find and xargs to correctly handle filenames with spaces in their names (3 个答案) 关闭 3
我正在创建一个在线订单系统,用于定期销售商品(蔬菜盒送货上门)。我有一个“订单”模型(简化)如下: class BoxOrder(models.Model): customer = model
我已经检查过我的应用程序产品大小约为 10MB,但是当我构建它进行归档时,它显示 Appstore 大小为 20MB,即它几乎翻了一番。但是当我在文件夹中看到存档时,它的大小仍然是 10MB,我不知道
我使用的是 Mercurial 1.7.2。在 Windows 上,我想提取指定更改集中的所有文件(在我的案例提示中)。这样我就可以只将我已更改的文件上传到我的网络服务器。 如果我想获取整个存储库的未
我正在为使用 iOS 6 的 iPad 项目开发 Objective-C 代码库。 在我将类“ClassA”的名称重构为“ClassB”之后,我发现以下测试失败了: NSData *encodedOb
我的 Xcode 项目能够在模拟器上成功构建和运行,但是当我尝试将其存档时出现一个问题,提示该项目无法导入桥接 header 。 这是在模拟器上运行的图像应用。 现在,当我尝试将其存档到通用 IOS
我是 IOS 新手。我已经开发了一个 IOS 应用程序,现在我想在 iTunes 上发布这个应用程序。我已经创建了证书、应用程序 ID,然后是临时配置文件。我已成功将此添加到“build设置”的“代码
我有一个文件,其中包含我想用 tar 归档的文件列表。我们称之为 mylist.txt 它包含: file1.txt file2.txt ... file10.txt 有没有办法可以发出以 mylis
我是一名优秀的程序员,十分优秀!