快速连续发出多个请求时 RestKit 崩溃
Posted
技术标签:
【中文标题】快速连续发出多个请求时 RestKit 崩溃【英文标题】:Crash with RestKit when issuing multiple requests in quick succession 【发布时间】:2012-07-28 10:05:57 【问题描述】:我有一个带有两个按钮的按钮,它们开始从带有RestKit 的网络服务器下载一些数据。
现在,如果用户快速连续地反复点击这两个按钮,我的应用就会崩溃并在下面生成崩溃日志。
我这样发起我的请求:
-(void)loadDataAtPath:(NSString *)path completion:(ResultArrayBlock)completionBlock failed:(ResultFailedBlock)failedBlock
RKObjectMapping *groupMapping = [Group mapping];
[self.objectManager.mappingProvider setMapping:groupMapping forKeyPath:@"groups.group"];
[self.objectManager.mappingProvider setObjectMapping:groupMapping forKeyPath:path];
[self.objectManager loadObjectsAtResourcePath:path usingBlock:^(RKObjectLoader *loader)
loader.onDidLoadObjects = ^(NSArray *array)
// Do the reverse mapping of the group
for (Group *c in array)
for(Person *p in c.persons)
p.group = c;
completionBlock(array);
;
loader.onDidFailWithError = failedBlock;
];
我首先认为问题出在 for 循环中,我在其中对数据进行了一些映射后设置,但即使在评论 for 循环时问题仍然存在。
奇怪的是,即使我打开 Network Link Conditioner.prefpane
,模拟器中也不会出现此问题崩溃
当我在设备上调试它时,我会在控制台上看到以下内容。
[PLCrashReport] Terminated stack walking early: Corrupted frame
[PLCrashReport] Terminated stack walking early: Corrupted frame
崩溃日志如下所示:
Application Specific Information:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x3c14a0> was mutated while being enumerated.'
Last Exception Backtrace:
0 CoreFoundation 0x3734e88f __exceptionPreprocess + 162
1 libobjc.A.dylib 0x35053259 objc_exception_throw + 32
2 CoreFoundation 0x3734e3b3 __NSFastEnumerationMutationHandler + 162
3 MyApp 0x0008f5bf -[RKObjectMapper performKeyPathMappingUsingMappingDictionary:] + 407
4 MyApp 0x0008fa45 -[RKObjectMapper performMapping] + 673
5 MyApp 0x0008ac7d -[RKObjectLoader mapResponseWithMappingProvider:toObject:inContext:error:] + 1045
6 MyApp 0x0008b04f -[RKObjectLoader performMapping:] + 575
7 MyApp 0x0008b22b __47-[RKObjectLoader performMappingInDispatchQueue]_block_invoke_0 + 247
8 libdispatch.dylib 0x3046ec59 _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x30479cab _dispatch_queue_drain + 274
10 libdispatch.dylib 0x30479b19 _dispatch_queue_invoke$VARIANT$up + 36
11 libdispatch.dylib 0x3047a78b _dispatch_worker_thread2 + 214
12 libsystem_c.dylib 0x33bbddfb _pthread_wqthread + 294
13 libsystem_c.dylib 0x33bbdcd0 start_wqthread + 8
【问题讨论】:
既然这是堆栈跟踪指示问题的地方,performKeyPathMappingUsingMappingDictionary
,那里面有什么?
【参考方案1】:
正如@PhillipMills 所建议的,当您查看 performKeyPathMappingUsingMappingDictionary 内部时,您可以轻松看到答案。您的问题是重复使用这些行设置映射:
[self.objectManager.mappingProvider setMapping:groupMapping forKeyPath:@"groups.group"];
[self.objectManager.mappingProvider setObjectMapping:groupMapping forKeyPath:path];
如果您在映射响应时调用此行,则会触发错误,因为您正在更改它试图快速枚举的同一个字典。
通常,您会在初始配置中的某处设置映射,而不是每次都这样。
【讨论】:
你说得对,这不是必需的。但是为什么这会导致枚举问题呢? 在后台线程中,您正在快速枚举一个集合,同时在主线程上对其进行修改。阅读 fast enumeration 以了解更多信息。以上是关于快速连续发出多个请求时 RestKit 崩溃的主要内容,如果未能解决你的问题,请参考以下文章