有没有一种在背景 dispatch_queue 上初始化 ObjC 对象的好方法?
Is there a good way to init an ObjC object on a background dispatch_queue?
我有一个需要大量初始化的 ObjC class RuleSet
(解析一个大 JSON 文件,对多个 OS 服务进行大量查询,应用启发式,最后,它构建了一组复杂的 NSPredicates
,稍后可用于快速评估。
我的程序(此对象除外)从 MacOS(EndpointSecurity 框架)接收高优先级事件,并且必须在非常短的期限内响应这些事件 - 基于我当前的快速评估 RuleSet
实例。
我在我创建的特殊(最高优先级)并发 dispatch_queue
中处理这些事件。
但是......如果我收到一些外部触发器,要更改我的 RuleSet
- 我需要在应用它之前构建新的 RuleSet
实例,我希望创建它的代码不了解dispatch queues的内部结构,简单调用
RuleSet *newRules = [[RuleSet alloc] initWithJSON:newJSONPath];
[myEventHandlingEngine setRuleSet:newRuleSet];
我希望 RuleSet init 能够以某种方式将工作推迟到另一个低优先级序列 dispatch_queue,也许是部分的。我不介意在我完成之前阻止调用者(这个繁重的初始化不应该超过一秒钟......)。不过,重要的是我在优先级较低的队列上执行此操作 - 以便首先处理传入的事件。
现在我试着写
- (instancetype) initWithJSON:newJSONPath:(NSString *)jsonFilePath
{
dispatch_sync([RuleSet setupQueue], ^{
if ( nil == (self = [super init]) ) {
self = nil;
return self;
}
// heavy work here
});
return self;
}
但这当然不会编译,因为 'self' 不是 __block 变量,我不确定它是否可以...
关于如何解决这个问题有什么建议吗?
您应该尝试使用 dispatchGroup 来处理这种情况:
- (instancetype) initWithJSON:newJSONPath:(NSString *)jsonFilePath
{
if ( nil == (self = [super init]) ) {
self = nil; //This seems useless since self is already nil ?
return self;
}
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, [OITPreventionPolicy policySetupQueue], ^{
// Execute your heavy work here
});
// Wait for the group to finish its work (you could replace 'forever' by a timeout)
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return self;
}
调用dispatch_group_wait
会阻塞创建对象的线程(所以不能是主线程)
我有一个需要大量初始化的 ObjC class RuleSet
(解析一个大 JSON 文件,对多个 OS 服务进行大量查询,应用启发式,最后,它构建了一组复杂的 NSPredicates
,稍后可用于快速评估。
我的程序(此对象除外)从 MacOS(EndpointSecurity 框架)接收高优先级事件,并且必须在非常短的期限内响应这些事件 - 基于我当前的快速评估 RuleSet
实例。
我在我创建的特殊(最高优先级)并发 dispatch_queue
中处理这些事件。
但是......如果我收到一些外部触发器,要更改我的 RuleSet
- 我需要在应用它之前构建新的 RuleSet
实例,我希望创建它的代码不了解dispatch queues的内部结构,简单调用
RuleSet *newRules = [[RuleSet alloc] initWithJSON:newJSONPath];
[myEventHandlingEngine setRuleSet:newRuleSet];
我希望 RuleSet init 能够以某种方式将工作推迟到另一个低优先级序列 dispatch_queue,也许是部分的。我不介意在我完成之前阻止调用者(这个繁重的初始化不应该超过一秒钟......)。不过,重要的是我在优先级较低的队列上执行此操作 - 以便首先处理传入的事件。
现在我试着写
- (instancetype) initWithJSON:newJSONPath:(NSString *)jsonFilePath
{
dispatch_sync([RuleSet setupQueue], ^{
if ( nil == (self = [super init]) ) {
self = nil;
return self;
}
// heavy work here
});
return self;
}
但这当然不会编译,因为 'self' 不是 __block 变量,我不确定它是否可以...
关于如何解决这个问题有什么建议吗?
您应该尝试使用 dispatchGroup 来处理这种情况:
- (instancetype) initWithJSON:newJSONPath:(NSString *)jsonFilePath
{
if ( nil == (self = [super init]) ) {
self = nil; //This seems useless since self is already nil ?
return self;
}
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, [OITPreventionPolicy policySetupQueue], ^{
// Execute your heavy work here
});
// Wait for the group to finish its work (you could replace 'forever' by a timeout)
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return self;
}
调用dispatch_group_wait
会阻塞创建对象的线程(所以不能是主线程)