#objective-c #ios #animation #recursion
#objective-c #iOS #Анимация #рекурсия
Вопрос:
Я закодировал это для циклического просмотра изображений на моем iPad, думая, что это приведет к переполнению стека очень скоро, но пока ничего. Это стабильно (не то, чтобы я жаловался). Но это случай открытия шампанского перед событием или…
- (void)showPhotos:(NSMutableArray *)resultSet index:(int)i
{
i = 1;
[UIView animateWithDuration:PHOTO_DISPLAY_TIME
delay:0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
//get photourl amp; set it to imageview
[self.photosImage setAlpha:1.0];
}
completion:^(BOOL finished)
{
if(finished)
{
[UIView animateWithDuration:PHOTO_DISPLAY_TIME
delay:0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void)
{
[self.photosImage setAlpha:0.0];
}
completion:^(BOOL finished)
{
if(finished)
[self showPhotos:resultSet index:i];
}];
}
}];
return;
}
То, что я делаю, — это затухание изображения и затухание изображения. и затем снова вызывает ту же функцию. Так что это должно произойти правильно?
Ответ №1:
Даже если это выглядит как рекурсивное, это не так. Блок завершения будет вызываться асинхронным после завершения анимации. Это произойдет после возврата вашего метода.
Если вы все еще не уверены в этом, вы можете проверить это в отладчике. Просто поместите точку останова при втором вызове вашего метода и проверяйте трассировку стека каждый раз, когда она срабатывает.
Ответ №2:
Блок завершения фактически не вызывается из showPhotos. Он вызывается в основном цикле выполнения. showPhotos помещает анимацию в очередь и завершает. Позже, когда анимация завершена, завершение ставится в очередь, и его запускает основной цикл выполнения. Исходный вызов showPhotos уже завершен. Так что вам не нужно беспокоиться о переполнении стека.
Ответ №3:
На самом деле это похоже на бесконечный цикл. Вы могли бы получить тот же эффект, программируя:
bool forever = YES;
while (forever) {
//fade in
//fade out
}
Это вызвало бы проблемы, если бы метод вызывал себя более одного раза внутри себя. Поскольку это создало бы экспоненциальные кратные функции, пытающиеся выполняться почти одновременно.
//this would cause issues
- (void)showPhotos:(NSMutableArray *)resultSet index:(int)i {
[self showPhotos:resultSet index:i];
[self showPhotos:resultSet index:i];
}
Комментарии:
1. Это неправильно, поскольку блоки завершения анимации называются асинхронными.