BLE + CoreData 导致冻结 (semaphore_wait_trap)
BLE + CoreData causes freeze (semaphore_wait_trap)
我正在开发一个应用程序,它将通过 CoreBluetooth (BLE) 接收数据并将其存储在 CoreData 中。它们单独工作时效果很好,但在一起时效果不佳,我认为这与线程有关。
我做什么
我正在使用单例来处理 CoreData 交互。单例初始化代码如下。初始化代码基本上是斯坦福课程 CS193p 的复制粘贴。
第一次访问单例是在CoreBluetooth从蓝牙外设接收到某个数据块时。请参阅下面的代码。
单例初始化
static SessionManager *sharedInstance;
+ (instancetype)sharedSessionManager
{
NSLog(@"Shared instance requested.");
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
首次访问 SessionManager
-(void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
// First some data processing
...
[[SessionManager sharedSessionManager] addMessageToCurrentSession:message];
}
会发生什么
在 -(instancetype) init
内,整个应用程序在下面的行冻结(零 CPU,没有内存增加)。
我还添加了断点到达此点时的线程图像(即在它执行之前)。
[self.document openWithCompletionHandler:^(BOOL success) {
if (success) [self documentIsReady];
if (!success) NSLog(@"Could not open document %@", [self.documentPath path]);
}];
我的问题
这是怎么回事,我做错了什么?
您的问题是您的 SessionManager
单例初始化存在竞争条件 - 您的 SessionManager
init 调用 openWithCompletionHandler
异步完成,因此 init
returns 在对象实际 被 初始化之前。
我建议您从 SessionManager
实现一个委托,以便它可以在初始化完成时回调。
我正在开发一个应用程序,它将通过 CoreBluetooth (BLE) 接收数据并将其存储在 CoreData 中。它们单独工作时效果很好,但在一起时效果不佳,我认为这与线程有关。
我做什么
我正在使用单例来处理 CoreData 交互。单例初始化代码如下。初始化代码基本上是斯坦福课程 CS193p 的复制粘贴。
第一次访问单例是在CoreBluetooth从蓝牙外设接收到某个数据块时。请参阅下面的代码。
单例初始化
static SessionManager *sharedInstance;
+ (instancetype)sharedSessionManager
{
NSLog(@"Shared instance requested.");
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
首次访问 SessionManager
-(void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
// First some data processing
...
[[SessionManager sharedSessionManager] addMessageToCurrentSession:message];
}
会发生什么
在 -(instancetype) init
内,整个应用程序在下面的行冻结(零 CPU,没有内存增加)。
我还添加了断点到达此点时的线程图像(即在它执行之前)。
[self.document openWithCompletionHandler:^(BOOL success) {
if (success) [self documentIsReady];
if (!success) NSLog(@"Could not open document %@", [self.documentPath path]);
}];
我的问题
这是怎么回事,我做错了什么?
您的问题是您的 SessionManager
单例初始化存在竞争条件 - 您的 SessionManager
init 调用 openWithCompletionHandler
异步完成,因此 init
returns 在对象实际 被 初始化之前。
我建议您从 SessionManager
实现一个委托,以便它可以在初始化完成时回调。