gpt4 book ai didi

ios - Firebase FSnapshotUtilities 由于在枚举时改变 NSMutableDictionary 而崩溃

转载 作者:行者123 更新时间:2023-12-01 19:00:25 25 4
gpt4 key购买 nike

编辑 根据接受的答案,解决方案是使用 mutableDeepCopy .您需要将其用于发送到 Firebase 的 setValue 的任何值。 ,以及从观察变化中返回的任何值。这是 Firebase 的 SDK 的一个已知问题,应该很快就会修复。

@interface NSDictionary (DeepCopy) 

- (NSDictionary*)mutableDeepCopy {
return (NSMutableDictionary *)CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)self, kCFPropertyListMutableContainers));
}

@end

我正在使用 Firebase 开发应用程序用于实时协作。 Firebase 库由于竞争条件而间歇性崩溃,它会改变 NSMutableDictionary在枚举它时。我在这里发布它是为了可见性,以及 Firebase 更喜欢使用 Stack Overflow 作为错误报告的主要方法这一事实。
*** Collection <__NSDictionaryM: 0xd8198f0> was mutated while being enumerated.
2014-04-27 09:39:45.328 SharedNotesPro[29350:870b] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSDictionaryM: 0xd8198f0> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x044711e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x03f3e8e5 objc_exception_throw + 44
2 CoreFoundation 0x04500cf5 __NSFastEnumerationMutationHandler + 165
3 SharedNotesPro 0x003fe8f5 +[FSnapshotUtilities nodeFrom:withPriority:] + 1405
4 SharedNotesPro 0x003fe373 +[FSnapshotUtilities nodeFrom:] + 51
5 SharedNotesPro 0x003fe971 +[FSnapshotUtilities nodeFrom:withPriority:] + 1529
6 SharedNotesPro 0x003e2504 -[FRepo setInternal:newVal:withPriority:withCallback:andPutId:] + 298
7 SharedNotesPro 0x003e23af -[FRepo set:withVal:withPriority:withCallback:] + 165
8 SharedNotesPro 0x00402aaf __61-[Firebase setValueInternal:andPriority:withCompletionBlock:]_block_invoke + 174
9 libdispatch.dylib 0x047a07b8 _dispatch_call_block_and_release + 15
10 libdispatch.dylib 0x047b54d0 _dispatch_client_callout + 14
11 libdispatch.dylib 0x047a3047 _dispatch_queue_drain + 452
12 libdispatch.dylib 0x047a2e42 _dispatch_queue_invoke + 128
13 libdispatch.dylib 0x047a3de2 _dispatch_root_queue_drain + 78
14 libdispatch.dylib 0x047a4127 _dispatch_worker_thread2 + 39
15 libsystem_pthread.dylib 0x04ae4dab _pthread_wqthread + 336
16 libsystem_pthread.dylib 0x04ae8cce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException

现在,我认为这是我的错……除了我已经尽一切可能阻止它。首先每一个 Firebase我创建的对象是完全 transient 的。也就是说,它是一次性的(分配给单个读/写操作)。此外,当我从 Firebase 加载数据时,我会创建内容的可变副本。

作为引用,这里是我创建的保存/加载方法;这存在于我创建的一个基类中,用作围绕 Firebase 的瘦包装器,它可以加载和保存数据。您可以找到完整的 .h.m这些要点中的文件。这些是我与 Firebase SDK 交互的唯一方式。另请注意,崩溃发生在后台线程上。
- (void)save:(void (^)(BOOL success))completionHandler {
Firebase *fb = [[Firebase alloc] initWithUrl:self.firebaseURL];
[fb setValue:[self.contents copy] withCompletionBlock:^(NSError *error, Firebase *ref) {
if(completionHandler) {
completionHandler(error ? NO : YES);
}
}];
}

- (void)save {
[self save:nil];
}

- (void)load:(void (^)(BOOL success))block {
Firebase *fb = [[Firebase alloc] initWithUrl:self.firebaseURL];
[fb observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
_contents = [[snapshot.value isKindOfClass:[NSDictionary class]]?snapshot.value:@{} mutableCopy];
block(_contents.allKeys.count > 0);
}];
}

最佳答案

编辑:这应该不再是问题,因为最新的 Firebase SDK 将在 setValue 调用中同步克隆您的对象。在将数据传递给 Firebase 之前不再需要手动克隆数据

尽管您正在调用“复制”,但这只是最外层 NSDictionary 的“浅”副本,因此如果您在外部 NSDictionary 中有任何 NSDictionaries,并且您正在修改它们,当 Firebase 枚举那些内部时,我们仍然会遇到此错误NSDictionary 对象,并且从调用堆栈中,看起来我们正在枚举内部对象之一。

Firebase 确实应该自动为您完成此副本,因此您不必担心它。我们打开了一个错误来解决这个问题。但就目前而言,您需要进行“深拷贝”而不是浅拷贝。请参阅此处了解一些可能的方法:deep mutable copy of a NSMutableDictionary (第二个或第三个答案看起来很不错)。

关于ios - Firebase FSnapshotUtilities 由于在枚举时改变 NSMutableDictionary 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23326161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com