Определение и использование замыканий в Задаче C - PullRequest
0 голосов
/ 14 марта 2011

Я пытаюсь написать универсальную функцию для запуска и завершения событий в моем приложении Obj-C (iOS).Я определяю - (void)startEvent:(void (^)())completion.В теле этой функции я выполняю действие, которое запускает анимацию.Что мне нужно, так это вызвать completion, когда пройдет определенный интервал времени.

Итак, я делаю копию completion и присваиваю ее глобальной переменной (в области видимости).

Вот как я это делаю:

void (^startEventCompletionClosure)();

- (void)startEvent:(void (^)())completion {
    // side note: I have NO access to "complete" closure of - [UIView animateWithDuration:...]
    ...
    [self performSelector:@selector(startEventCompleted) withObject:nil afterDelay:kDealy];
    startEventCompletionClosure = [completion copy];
}

- (void)startEventCompleted {
    startEventCompletionClosure();
    [startEventCompletionClosure release];
}

Но у меня есть несколько вопросов:

  • Это лучший способ справиться с этим?
  • __блокировать объект NSObject?декларация C?
  • Почему я должен copy это?Разве нельзя retain это?
  • Если это не объект Obj-C, почему я могу вызывать [... copy] и [... retain] как бы?

Спасибо за чтение!

Ответы [ 3 ]

2 голосов
/ 14 марта 2011

Это лучший способ справиться с этим?

В зависимости от вашего использования, вы можете сохранить это как переменную экземпляра (если вы действительно не хотите, чтобы блок был разделен междуклассы и, таким образом, изменяются для всех классов в любое время, когда вызывается startEvent:.

Является ли __block объектом NSObject?объявление C?

Это спецификатор хранилища C.

Почему я должен его копировать?Разве нельзя просто сохранить его?

Вы можете сохранить его, но, вероятно, он не будет делать то, что вы хотите, чтобы он делал.В C и Objective-C блоки создаются в стеке.Когда вы копируете его, он (и любые закрытые переменные) копируются в кучу.Если вы сохраните его, он и его переменные не будут скопированы в кучу.

Если это не объект Obj-C, почему я могу вызывать [... copy] и [... retain] как бы?

Магия.:) Более серьезно, в Objective-C блоки предназначены для работы в качестве объектов Objective-C.(Это похоже на причину, по которой вы можете плавно приводить значения между NSString и CFStringRef - объекты созданы таким образом, чтобы это было возможно.)

1 голос
/ 14 марта 2011

Во-первых, мы называем их «блоками», а не «замыканиями» в Objective-C. Во-вторых, -performSelector:withObject:afterDelay: - это то, что мы использовали до того, как у нас были блоки. В наши дни вам, вероятно, следует использовать dispatch_after(). Наконец, блоки являются объектами и соответствуют протоколу NSObject.

0 голосов
/ 17 марта 2011

UIView теперь также имеет приятные блочные методы анимации ...

animateWithDuration: animations: animateWithDuration: animations: завершение: animateWithDuration: задержка: параметры: анимации: завершение:

[UIView animateWithDuration:kAnimationDurationTime animations:^{
    // animate some animatable properties
    // do some other stuff
  } completion:^(BOOL finished) {
    // code that you want to run
    //  when the animation has finished
}];

Я нашел это очень полезным способом оживить вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...