gpt4 book ai didi

objective-c - NSOperation & 单例 : Correct concurency design

转载 作者:搜寻专家 更新时间:2023-10-30 20:20:50 25 4
gpt4 key购买 nike

我在这里需要你们对我的应用程序设计的建议,基本上我想知道它是否会像我预期的那样工作?由于多线程是非常棘手的事情,我想听听您的意见。

基本上我的任务很简单 - 我有 SomeBigSingletonClass - 大单例类,它有两个方法 someMethodOnesomeMethodTwo 这些方法应该定期调用(基于计时器)并在单独的线程中调用。但是目前每个线程应该只有一个实例,例如在任何时候都应该只有一个运行 someMethodOne 并且同样运行 someMethodTwo

我尝试过的

GCD - 是否使用 GCD 实现,但它缺少非常重要的功能,它不提供检查当前是否有任何正在运行的任务的方法,即我无法检查是否有假设只有一个正在运行的实例 someMethodOne 方法。

NSThread - 它确实提供了很好的功能,但我很确定 NSOperation 和 GCD 等新的高级技术将使我的代码维护变得更加简单。所以我决定放弃 NSThread。

我使用 NSOperation 的解决方案我打算如何实现双线程调用

@implementation SomeBigSingletonClass

- (id)init
{
...
// queue is an iVar
queue = [[NSOperationQueue alloc] init];

// As I'll have maximum two running threads
[queue setMaxConcurrentOperationCount:2];
...
}

+ (SomeBigSingletonClass *)sharedInstance
{
static SomeBigSingletonClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[SomeBigSingletonClass alloc] init];
});
return sharedInstance;
}

- (void)someMethodOne
{
SomeMethodOneOperation *one = [[SomeMethodOneOperation alloc] init];
[queue addOperation:one];
}

- (void)someMethodTwo
{
SomeMethodTwoOperation *two = [[SomeMethodOneOperation alloc] init];
[queue addOperation:two];
}
@end

最后我的 NSOperation 继承类看起来像这样

@implementation SomeMethodOneOperation

- (id)init
{
if (![super init]) return nil;
return self;
}

- (void)main {
// Check if the operation is not running
if (![self isExecuting]) {
[[SomeBigSingletonClass sharedInstance] doMethodOneStuff];
}
}

@end

SomeMethodTwoOperation 操作类也是如此。

最佳答案

如果您正在使用 NSOperation,您可以通过创建自己的 NSOperationQueue 并将 numberOfConcurrentOperations 设置为 1 来实现您想要的效果。

您也可以使用 @synchronized 作用域作为您的类的锁定对象。

编辑:澄清---

我的提议:

队列 A(1 个并发操作 -- 用于一次执行一次 SomeMethodOneOperation SomeMethodTwoOperation)

队列B(n个并发操作——用于执行一般的后台操作)

编辑 2:更新代码说明运行最大操作一和操作二的方法,在任何给定时间执行操作一和操作二的最大值。

-(void)enqueueMethodOne
{
static NSOperationQueue * methodOneQueue = nil ;
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
queue = [ [ NSOperationQueue alloc ] init ] ;
queue = 1 ;
});

[ queue addOperation:[ NSBlockOperation blockOperationWithBlock:^{
... do method one ...
} ] ];
}

-(void)enqueueMethodTwo
{
static NSOperationQueue * queue = nil ;
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
queue = [ [ NSOperationQueue alloc ] init ] ;
queue = 1 ;
});

[ queue addOperation:[ NSBlockOperation blockOperationWithBlock:^{
... do method two ...
} ] ];
}

编辑 3:

根据我们的讨论:

我指出 isExecuting 是一个成员变量,仅指被查询操作的状态,而不是该类的任何实例是否正在执行

因此,Deimus 的解决方案无法同时运行一个操作的多个实例,例如

关于objective-c - NSOperation & 单例 : Correct concurency design,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11594888/

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