问题描述
有多个调用特定方法的资源,但我想确保(每个对象)仅被调用一次
There are multiple sources calling a particular method, but I would like to ensure that it is called exactly once (per object)
我想使用类似的语法
// method called possibly from multiple places (threads)
-(void)finish
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self _finishOnce]; // should happen once per object
});
}
// should only happen once per object
-(void)_finishOnce{...}
问题是令牌在同一个类的所有实例之间共享-所以不是一个很好的解决方案-每个对象是否都有一个dispatch_once_t-如果不是,确保它被调用一次的最佳方法是什么?
Problem is the token is shared accross all instances of the same class - so not a good solution - is there a dispatch_once_t per object - if not what is the best way to ensure it is called once?
这是我正在考虑的提议解决方案-看起来还好吗?
Here is a proposed solution I am thinking of - does it seem alright?
@interface MyClass;
@property (nonatomic,strong) dispatch_queue_t dispatchOnceSerialQueue; // a serial queue for ordering of query to a ivar
@property (nonatomic) BOOL didRunExactlyOnceToken;
@end
@implementation MyClass
-(void)runExactlyOnceMethod
{
__block BOOL didAlreadyRun = NO;
dispatch_sync(self.dispatchOnceSerialQueue, ^{
didAlreadyRun = _didRunExactlyOnceToken;
if (_didRunExactlyOnceToken == NO) {
_didRunExactlyOnceToken = YES;
}
});
if (didAlreadyRun == YES)
{
return;
}
// do some work once
}
推荐答案
Avner,您可能很遗憾现在才问到;-)
Avner, you're probably regretting you asked by now ;-)
关于对问题的编辑,并考虑到其他问题,您或多或少地重新创建了老派"方式,也许这正是您应该做的(直接输入代码,请输入错字):
Regarding your edit to the question, and taking into account other issues, you've more-or-less recreated the "old school" way of doing this, and maybe that is just what you should do (code typed in directly, expect typos):
@implemention RACDisposable
{
BOOL ranExactlyOnceMethod;
}
- (id) init
{
...
ranExactlyOnceMethod = NO;
...
}
- (void) runExactlyOnceMethod
{
@synchronized(self) // lock
{
if (!ranExactlyOnceMethod) // not run yet?
{
// do stuff once
ranExactlyOnceMethod = YES;
}
}
}
对此有一个通用的优化,但是在其他讨论之后,让我们跳过这一点.
There is a common optimization to this, but given the other discussion let's skip that.
这是便宜"吗?可能不是,但是所有事情都是相对的,它的花费可能并不大-但是YMMV!
Is this "cheap"? Well probably not, but all things are relative, its expense is probably not significant - but YMMV!
HTH
这篇关于对每个对象而不对每个类使用dispatch_once_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!