0

Скажем, у меня есть подкласс UIView, который я назову AnimatableView, где моя реализация layoutSubviews содержит некоторые внутренние материалы.NSOperation, который будет работать при запуске UIView перед layoutSubviews, называется

AnimatableView также метод commenceAnimationLoop который выглядит примерно так:

- (void) commenceAnimationLoop { 

    NSOperation *animationLoop = [[AnimationLoopOperation alloc]init]; 
    [queue addOperation:animationLoop]; //queue is a NSOperationQueue iVar of AnimatableView 
    [animationLoop release]; 
} 

AnimationLoopOperation является подклассом NSOperation которого main метод запуска бесконечной анимации, который выходит только после того, как isCancelled свойства становится YES.

Проблема, которую я имею в моем ViewController где я установить и анимировать экземпляр AnimatableView так:

- (void) viewDidLoad { 
    AnimatableView *animatableView = [AnimatableView alloc]initWithFrame:someFrame]; 

    [self.view addSubview: animatableView]; 
    [animatableView commenceAnimationLoop]; 

    [animatableView release]; 
} 

Проблема заключается в том, что NSOperation создан в commenceAnimationLoop выполняется перед моим экземпляром AnimatableView была возможность позвонить layoutSubviews (что означает, что контент еще не создан и не выложен).

творю догадка, что метод layoutSubviews называется позже (когда ViewController готов предоставить свою точку зрения иерархии?), Но что метод commenceAnimationLoop порождает поток, который непосредственно выполняет в фоновом режиме.

Подводя итог - что было бы лучшим способом сделать мою операцию animationLoop ждать представления до макета до начала?

Чтобы обеспечить некоторый контекст высокого уровня для того, чего я пытаюсь достичь, я использую NSOperation, чтобы начать непрерывную анимацию. Идея состоит в том, что я могу предоставить метод endAnimation, который, скорее всего, вызовет cancelAllOperations в моей очереди. Все это делается в надежде, что я могу обеспечить способ запуска, а затем прервать бесконечную анимацию двумя способами: commenceAnimationLoop и endAnimation. Возможно, я лаяю неправильное дерево, идущее по пути многопоточности?

+1

Если вам нужно layoutSubviews для запуска до вашей операции, вы должны запустить очередь операций (используйте 'setSuspended: YES'), пока она не закончится. Вы можете запустить рабочую очередь ('setSuspended: NO') в' viewDidAppear' ... –

+0

Вышеописанное и это действительно простое решение. Добавьте его в качестве ответа, и я соглашусь с ним. – Barjavel

ответ

2

Если вам нужно layoutSubviews для выполнения перед вашей работой, тогда вы должны запустить рабочую очередь до этого. Вы можете предотвратить запуск очереди операций дополнительных операций с использованием [myOperationQueue setSuspended:YES];.

Поскольку это приведет к тому, что очередь не начнет новые операции, вы должны приостановить очередь, прежде чем добавлять к ней свои операции.

После того, как вы просмотрели загрузку и запущен layoutSubviews, вы можете снова возобновить работу с помощью [myOperationQueue setSuspended:NO];. Одно место для этого может быть в viewDidAppear.

Смежные вопросы