我有一个计时器,如果它不是 nil,则对属性执行操作,但是在检查 nil 和执行操作之间,一个事件将属性设置为 nil。实际上有几个事件都可以将属性设置为 nil。计时器正在检查的还有其他属性在同一条船上。
解决这个问题的最优雅和可扩展的方法是什么?
- 将属性的每次使用都包装在同步块中?
- 在计时器开始时设置/释放锁并检查每个事件中的等待锁?
- 还有什么?
我有一个计时器,如果它不是 nil,则对属性执行操作,但是在检查 nil 和执行操作之间,一个事件将属性设置为 nil。实际上有几个事件都可以将属性设置为 nil。计时器正在检查的还有其他属性在同一条船上。
解决这个问题的最优雅和可扩展的方法是什么?
我不太确定您的确切情况,但您可能想考虑为属性编写一个自定义设置器,当它设置为 nil 时将取消计时器?
我选择了 Paul de Lange 的回答,因为这对我来说很有意义。我不想找到我设置属性的每个地方并将其包装在一个@synchronized
块中。
对于需要做类似事情的其他人,这是我想出的代码:
@interface MyClass {
//...
//The iVar, note that the iVar has a different name than the property, see the @synthesize command
RefreshOperation *_refreshOperation;
//...
}
@property (nonatomic, retain) RefreshOperation *refreshOperation;
@implementation MyClass
//...
//The timer's callback
- (void)statusTimerEvent:(NSTimer *)aTimer
{
//Block/wait for thread safe setters/getters
@synchronized(self)
{
if (self.refreshOperation)
{
self.status = [self.refreshOperation status];
progressView.progress = self.refreshOperation.progress;
}
}
}
//...
//Thread safe setter for the refreshOperation property
- (void)setRefreshOperation:(RefreshOperation *)refreshOperation:(RefreshOperation *)newRefreshOperation
{
@synchronized(self)
{
if (_refreshOperation != newRefreshOperation)
{
[_refreshOperation release];
_refreshOperation = [newRefreshOperation retain];
}
}
}
//Thread safe getter for the refreshOperation property
- (RefreshOperation *)refreshOperation
{
id result = nil;
@synchronized(self)
{
result = [_refreshOperation retain];
}
return [result autorelease];
}
//...
- (void)dealloc
{
//...
self.refreshOperation = nil;
[super dealloc];
}
//...
//Connect the property |refreshOperation| to the iVar |_refreshOperation|; having the same name for both results in warning about the local variable hiding a property
@synthesize refreshOperation = _refreshOperation;