0

я написал и использовал немного обработчик завершения только на практике прибивали вниз блоки -Понимание обработчиков пользовательских завершающие

-(void)delayAndSetCompletionBlock:(void (^)(BOOL))completed { 
    //set a delay timer 
    double delayInSeconds = 2.0; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     //code to be executed on the main queue after delay 
     completed(YES); 
    }); 
} 

В ВК в другом месте, я проверить переменную завершения; если блок завершен, я меняю цвет фона на что-то еще.

Мой вопрос в том, что в методе delayAndSetCompletionBlock у нас есть аргумент, который является блоком. Блок имеет возвращаемый тип void, принимает параметр Bool в качестве параметра, а аргумент BLOCK называется завершенным. Как это относится к дальнейшему снижению кода, в котором я указываю completed(YES)?

Я просто смущен относительно того, что completed(YES) связано с блоком, который я передал в качестве аргумента метода. completed - это имя типа блока, передаваемого методу, поэтому я говорю «выполнить блок, который мы дали методу, и передать YES в качестве логического параметра, который требуется»? Если да, то как блок знает, что делать с этим YES?

+0

Я предполагаю, что комментарий «// code to be ....» является заполнителем для кода, который будет выполнен после короткой задержки. Последнее, что delayAndSetCompletionBlock: будет делать, это вызвать блок, который он дал в качестве аргумента. Если вы можете представить какое-либо обстоятельство в коде места-заполнителя, где что-то пойдет не так, вы можете называть его завершенным (НЕТ). Блок, вызванный завершением, может использовать параметр BOOL, чтобы увидеть, действительно ли код действительно завершился. –

ответ

0

Вы объявили метод с единственным аргументом, названным completed. Этот аргумент является блоком, который возвращает void и ожидает одиночный аргумент BOOL, неназванный в вашем случае.

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

-(void)delayAndSetCompletionBlock:(void (^)(BOOL completed))completionBlock; 

Таким образом, ваше предположение

так я говорю «выполнить блок, который мы дали метод и передать YES в качестве логического параметра это берет "?

был верным.

Если да, то каким образом блок знает, что делать с этим «ДА»?

Caller вашего метода, как правило, обеспечивает реализацию блока. Например:

[self delayAndSetCompletionBlock:^void (BOOL completed) { 
    if (completed) { 
     NSLog(@"done!"); 
    } 
}]; 

У него будут некоторые ожидания относительно того, что делает ваш метод. Если ваш метод является общедоступным, надеюсь, вы его задокументируете, и укажите, когда будет вызываться completionBlock, и каково значение аргумента блока. Возможно, вы, по крайней мере, представите комментарий в заголовочном файле. Кроме того, возможно, что код самодокументирован, поэтому любой разработчик с опытом Objective-C будет ожидать аналогичного поведения и аргументов блока.

+0

Я предполагаю, что мое замешательство заключается в вызове блока. В реализации блока мы устанавливаем логическое значение YES независимо от того, какой объект вызывает этот блок. Когда мы вызываем блок (например, в VC), мы передаем блок, который имеет тот же тип возврата и параметр, что и блок в нашем определенном методе (delayAndSetCompletionBlock).Он перейдет к исходной реализации блока (где мы устанавливаем значение bool равным YES), независимо от того, что мы делаем с блоком в VC, правильно? Это в конечном счете, как это работает. –

+0

С блоками в общем случае мы можем их где-то определить и выбрать НИЧЕГО с аргументами, а вместо этого, когда мы вызываем этот блок где-нибудь, что-то делаем с аргументами THERE (как в VC)? Но в этом случае мы фактически изначально манипулируем одним из аргументов в начальной реализации, и в этом заключается суть блока завершения? –

+0

Не уверен, что я вас правильно понимаю. Просто чтобы убедиться: тело блока не выполняется в точке, когда вызывается 'delayAndSetCompletionBlock'. Он выполняется только тогда, когда блок вызван внутри реализации метода. После этого у нас есть способ передать любые данные из реализации метода в точку, где метод вызывается через аргументы блока. Эти данные недоступны вне тела блока. –