同步 NSKeyedArchiver 或 NSUserDefaults
我有一个单例延迟事务管理器类,它负责对由于各种因素(网络可达性、邻近性等)而无法完成的 iphone 到应用程序服务器事务进行排队和出队。当可达性/邻近性恢复时,它会尝试使事务出队。出队的同时也可能有另一个事务入队。
我的理解是 NSUserDefaults 是可变字典的线程安全包装 SO 链接正是我想要的。同一个 SO 链接认为 NSUserDefaults 用于用户首选项。
这些交易不是用户偏好,而是我想要的功能。 所以,问题是,我可以在不损坏字典的情况下读取/写入/同步 NSUserDefaults 中事务的 NSMutableDictionary,还是需要通过使用 NSKeyed(Un)Archiver 进行读写来实现自己的锁定机制(见下文)?
一些代码:
- (void) queThing:(Thing *)aThing {
// @synchronized this block?
NSMutableDictionary * QD = [self readFile];
[QD setObject:aThing forKey:aThing.thingId];
[self writeFile: QD];
// @ sync?
}
- (void) writeFile:(NSMutableDictionary *)theData {
BOOL status = [NSKeyedArchiver archiveRootObject: theData toFile:archivePath];
if ( !status) {
DebugLog(@"Write to archive failed.");
} else {
DebugLog(@"Write to archive SUCCEEDED.");
}
}
- (NSMutableDictionary *) readFile {
NSMutableDictionary *Q =[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];
if ( ! Q ) {
Q = [NSMutableDictionary dictionaryWithCapacity:2];
}
return Q;
}
出队:
// @synchronized this block?
NSMutableDictionary * QD = [self readFile];
[QD removeObjectForKey:thing.thingId];
[self writeFile: QD];
// @ sync?
I have a singleton delayed-transaction manager class, which is responsible for enqueueing and dequeueing iphone-to-app-server transactions that cannot complete due to a variety of factors (network reachability, proximity, etc). When reachability/proximity is restored, it attempts to dequeue the the transactions. It is also possible that another transaction would be enqueued at the same time that dequeueing is happening.
My understanding is that NSUserDefaults is a thread-safe wrapper of a mutable dictionary SO link which is exactly what I want. That same SO link opines that NSUserDefaults is for user preferences.
These transactions are not user preferences but that's the functionality I want.
So, here's the question, can I read/write/synchronize an NSMutableDictionary of transactions in NSUserDefaults without corrupting the dictionary, or do I need to implement my own locking mechanism with reading and writing with NSKeyed(Un)Archiver (see below)?
Some code:
- (void) queThing:(Thing *)aThing {
// @synchronized this block?
NSMutableDictionary * QD = [self readFile];
[QD setObject:aThing forKey:aThing.thingId];
[self writeFile: QD];
// @ sync?
}
- (void) writeFile:(NSMutableDictionary *)theData {
BOOL status = [NSKeyedArchiver archiveRootObject: theData toFile:archivePath];
if ( !status) {
DebugLog(@"Write to archive failed.");
} else {
DebugLog(@"Write to archive SUCCEEDED.");
}
}
- (NSMutableDictionary *) readFile {
NSMutableDictionary *Q =[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];
if ( ! Q ) {
Q = [NSMutableDictionary dictionaryWithCapacity:2];
}
return Q;
}
Dequeue:
// @synchronized this block?
NSMutableDictionary * QD = [self readFile];
[QD removeObjectForKey:thing.thingId];
[self writeFile: QD];
// @ sync?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
NSUserDefaults 确实是线程安全的(它 文档中是这么说的)。但从概念上讲,它确实不适合做像你这样的事情。它会起作用,但最终您的事务 ID 可能会污染首选项命名空间,您可能会发现稍后想要将其与首选项捆绑包等一起使用。
围绕读/写进行锁定应该可以。对我来说,对文件操作加锁感觉很奇怪;您还可以将队列对象保留在内存中(带锁定),并且仅从主线程等定期刷新它。或者使用磁盘上的锁定文件来保护写入/读取。
It's true that
NSUserDefaults
is thread safe (it says so in the docs). But conceptually, it's really not the place to be doing stuff like you're doing. It will work, but you'll end up with your transaction IDs potentially polluting a preferences namespace that you may find you want to use later with a preferences bundle, etc.Doing locking around the reads/writes should work. Putting locks around file ops feels weird to me; you could also keep the queue object in memory (with locking) and only flush it periodically from e.g. the main thread. Or use a lockfile on disk to protect the writes/reads.