为什么我在不修改源 array/set 的代码中得到 NSFastEnumerationMutationHandler?
Why am I getting NSFastEnumerationMutationHandler in code that doesn't modify source array/set?
在我最新的应用程序版本的崩溃日志中,我得到了一个 NSFastEnumerationMutationHandler
,然后是我的代码的崩溃引用 HKAnchoredObjectQuery initWithType
,但我并不是故意改变 NSMutableSet sources
我正在快速枚举。
这是我的代码:
for(HKSource* source in sources){
NSPredicate *predicate = [HKQuery predicateForObjectsFromSources:[NSSet setWithObject:source]];
HKAnchoredObjectQuery *newQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType predicate:predicate anchor:anchor limit:HKObjectQueryNoLimit completionHandler:^(HKAnchoredObjectQuery *query, NSArray *results, NSUInteger newAnchor, NSError *error) {
completion(results);
}];
[healthStore executeQuery:newQuery];
}
关于我触发 NSFastEnumerationMutationHandler
的原因有什么建议吗?我没有明确接触 sources
也没有复制它...有没有办法 HealthKit
可以修改 source
?即使是,我认为修改 source
不应该触发它,因为我没有直接接触 sources
。任何故障排除建议或错误发现将不胜感激。
以下是崩溃日志中的确切文本:
Latest Exception Backtrace:
1. libobjc.A.dylib objc_exception_throw
2. CoreFoundation _NSFastEumerationMutationHandler
3. App name 0x1000d8000
4. App name 0x1000d8000
5. App name 0x1000d8000
6. HealthKit _79-[HKAnchoredObjectQuery initWithType:predicate:anchor:limit:completionHandler:]_block_invoke <---this must be referring to my code above, as it's the only call to initWithType inside a fast enumeration
7. HealthKit _81-[HKAnchoredObjectQuery deliverSampleObjects:deletedObjects:withAnchor:forQuery:]_block_invoke_2 <-- this is an internal HealthKit call. deliverSampleObjects is not a publicly listed method of the interface.
我的 SIM 卡或我的 phone 都没有崩溃,所以这是我必须继续的唯一信息。
看起来这发生在名为
的方法中某处的块中
[HKAnchoredObjectQuery initWithType:predicate:anchor:limit:completionHandler:]
所以我的猜测是有问题的块是完成处理程序,并且完成处理程序被异步调用 - 而其他人正在遍历同一个数组并可能修改它。
不幸的是,这个错误不显示是谁造成了麻烦,只显示了谁在找麻烦。我会在您自己的回调上设置一个断点,检查它是否是从快速枚举中调用的,并尝试找出还有谁可能正在修改数据。祝你好运。
代码段中名为 completion()
的块调用的一些代码正在迭代另一个集合,并且在修改该数组时这样做。请记住,HKAnchoredObjectQuery
的 completionHandler
在后台线程上运行,因此当 completionHandler
被调用时,您的代码可能正在对对象执行不安全的并发操作。
在我最新的应用程序版本的崩溃日志中,我得到了一个 NSFastEnumerationMutationHandler
,然后是我的代码的崩溃引用 HKAnchoredObjectQuery initWithType
,但我并不是故意改变 NSMutableSet sources
我正在快速枚举。
这是我的代码:
for(HKSource* source in sources){
NSPredicate *predicate = [HKQuery predicateForObjectsFromSources:[NSSet setWithObject:source]];
HKAnchoredObjectQuery *newQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType predicate:predicate anchor:anchor limit:HKObjectQueryNoLimit completionHandler:^(HKAnchoredObjectQuery *query, NSArray *results, NSUInteger newAnchor, NSError *error) {
completion(results);
}];
[healthStore executeQuery:newQuery];
}
关于我触发 NSFastEnumerationMutationHandler
的原因有什么建议吗?我没有明确接触 sources
也没有复制它...有没有办法 HealthKit
可以修改 source
?即使是,我认为修改 source
不应该触发它,因为我没有直接接触 sources
。任何故障排除建议或错误发现将不胜感激。
以下是崩溃日志中的确切文本:
Latest Exception Backtrace:
1. libobjc.A.dylib objc_exception_throw
2. CoreFoundation _NSFastEumerationMutationHandler
3. App name 0x1000d8000
4. App name 0x1000d8000
5. App name 0x1000d8000
6. HealthKit _79-[HKAnchoredObjectQuery initWithType:predicate:anchor:limit:completionHandler:]_block_invoke <---this must be referring to my code above, as it's the only call to initWithType inside a fast enumeration
7. HealthKit _81-[HKAnchoredObjectQuery deliverSampleObjects:deletedObjects:withAnchor:forQuery:]_block_invoke_2 <-- this is an internal HealthKit call. deliverSampleObjects is not a publicly listed method of the interface.
我的 SIM 卡或我的 phone 都没有崩溃,所以这是我必须继续的唯一信息。
看起来这发生在名为
的方法中某处的块中[HKAnchoredObjectQuery initWithType:predicate:anchor:limit:completionHandler:]
所以我的猜测是有问题的块是完成处理程序,并且完成处理程序被异步调用 - 而其他人正在遍历同一个数组并可能修改它。
不幸的是,这个错误不显示是谁造成了麻烦,只显示了谁在找麻烦。我会在您自己的回调上设置一个断点,检查它是否是从快速枚举中调用的,并尝试找出还有谁可能正在修改数据。祝你好运。
代码段中名为 completion()
的块调用的一些代码正在迭代另一个集合,并且在修改该数组时这样做。请记住,HKAnchoredObjectQuery
的 completionHandler
在后台线程上运行,因此当 completionHandler
被调用时,您的代码可能正在对对象执行不安全的并发操作。