ero*_*ppa 5 iphone cocoa-touch objective-c uikit
我们在iPhone SDK中有一个委托方法.问题是,操作系统在同一时间调用此方法两次.这个方法做了一些繁重的工作,所以我不想执行两次逻辑.有什么好方法可以检测到这种情况并阻止其中一个运行?
忘了提一下,它是从不同的线程调用的.
nal*_*all 10
一种方法是您在输入方法时设置的BOOL成员,并在离开时清除.如果在输入时设置了变量,您知道它已经在执行并且可以返回.
假设您是从多个线程调用的,那么您将需要锁定对此关键检查/设置区域的访问.NSLock对此有好处.
下面的代码有两个实现:myMethod1使用NSLock,myMethod2使用@synchronize显示.
@interface MyClass : NSObject
{
NSLock* theLock;
BOOL isRunning;
}
@end
@implementation MyClass
-(id)init
{
self = [super init];
if(self != nil)
{
theLock = [[NSLock alloc] init];
isRunning = NO;
}
return self;
}
-(void)dealloc
{
[theLock release];
[super dealloc];
}
// Use NSLock to guard the critical areas
-(void)myMethod1
{
[theLock lock];
if(isRunning == YES)
{
[theLock unlock]; // Unlock before returning
return;
}
isRunning = YES;
// Do fun stuff here
isRunning = NO;
[theLock unlock];
}
// This method uses @synchronize
-(void)myMethod2
{
@synchronized(self)
{
if(isRunning == YES)
{
return;
}
isRunning = YES;
// Do stuff here.
isRunning = NO;
}
}
@end
Run Code Online (Sandbox Code Playgroud)
哇.答案是正确的,但过度设计.只是用@synchronized().
foo.h中:
@interface Foo
{
id expensiveResult;
}
- (void) bar;
@end
Run Code Online (Sandbox Code Playgroud)
Foo.m:
@implementation Foo
- (void) bar
{
@synchronized(self) {
if (expensiveResult) return expensiveResult;
.... do expensive stuff here ....
expensiveResult = [theResult retain];
}
return expensiveResult;
}
@end
Run Code Online (Sandbox Code Playgroud)
如果你有多个Foo实例并希望保证所有实例的排他性,那么创建一个全局变量+(void)initialize- 一个NSString就可以了 - 并且就此@synchronized()而言.
但是,您的问题提出了一个更重要的问题.特别是,除非您非常明确地将应用程序配置为导致确实发生这种情况,否则永远不会同时调用同一方法两次.
答案提供的声音更像是对症状的修复,而不是对真正问题的修复.
注意:这依赖于expensiveResultnil,因为所有iVars在实例化时都是零.显然,如果要重新计算,请将ivar重置为nil.
| 归档时间: |
|
| 查看次数: |
5614 次 |
| 最近记录: |