ожидание заблокированного NSLock, пока tryLock не преуспеет - PullRequest
0 голосов
/ 19 апреля 2011

У меня есть класс с 2 методами, первый создает анимацию за секунду, а второй выполняет некоторую задачу.

Этот класс вызывается из второго класса для последовательного выполнения этих двух операций, но яхочу применить блокировку так, чтобы вторая операция выполнялась только после завершения первой.

Мой вопрос: каков наилучший способ сделать это?

вот мой код:

@implementation Server


- (id)init{

    if ( (self = [super init]) ) {
        syncLock = [[NSLock alloc] init];
    }
    return self;
}

- (void)operationA {
    NSLog(@"op A started");

    [syncLock lock];

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
    [view setBackgroundColor:[UIColor redColor]];
    [[[[UIApplication sharedApplication] delegate] window] addSubview:view];

    [UIView beginAnimations:@"opA" context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationFinished)];
    [UIView setAnimationDuration:1.5f];
    [view setFrame:CGRectMake(50, 50, 150, 150)];
    [UIView commitAnimations];

}
- (void)animationFinished {
    [syncLock unlock];
    NSLog(@"Op A finished");

}

- (void)operationB {
    if ( ![syncLock tryLock]) {
        [[NSRunLoop currentRunLoop] addTimer:[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(operationB) userInfo:nil repeats:NO] forMode:NSDefaultRunLoopMode];
        return;
    }
    NSLog(@"op B started");

    NSLog(@"perform some task here");
    [syncLock unlock];
    NSLog(@"op B finished");
}
@end

И код, который его вызывает:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    [self.window makeKeyAndVisible];

    Server *server = [[Server alloc] init];
    [server operationA];
    [server operationB];

    return YES;
}

1 Ответ

1 голос
/ 19 апреля 2011

Опция 1

Измените операцию A на метод BOOL и верните ДА после завершения и в вашем AppController

if([server operationA]) // operation A returns YES when completed so run operationB
    [server operationB];

Опция 2 добавлено согласно комментарию JeremyP

в вашем методе делегата (animationFinished :) для OperationA добавьте [self operationB]; для запуска operationB: в конце цикла анимации.

...