Рекурсия не завершается сбоем

#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. Это неправильно, поскольку блоки завершения анимации называются асинхронными.