2015-11-12 3 views
1

У меня есть метод с обратным вызовом, который выглядит примерно так:Передача переменной аннулирует ^() блок

- (void)doStuff:(void ^())callback 
{ 
    //Do a whole bunch of stuff 

    //Perform callback 
    callback(); 
} 

Я бы тогда этот метод вызывается позже, как это:

[self doStuff:^{[self callbackMethod];}]; 

Это прекрасно работает, когда нет данных для передачи, но теперь у меня есть некоторые данные, которые мне нужно передать между методами.

Рассмотрим следующий метод:

- (void)showAViewWithOptions:(int)options 

В этом методе, я показываю вид с определенными опциями, но если есть что-то другое уже на экране, я вызываю метод, чтобы скрыть его с помощью обратного вызова обратно Этот метод.

Таким образом, реализация выглядит так.

- (void)hideOldView:(void ^())callback 
{ 
    //Hide all objects in _oldViews and set _oldViews = nil 

    callback(); 
} 

- (void)showAViewWithOptions:(int)options 
{ 
    if(_oldViews != nil) 
    { 
     [self hideOldView:^(int options){[self showAViewWithOptions:options];}]; 
     return; 
    } 

    //Show the new view 
} 

компилируется и работает без проблем, но options теряет свою ценность после того, как прошло.

Честно говоря, это удивило меня, что оно скомпилировано, поскольку я думал, что он не примет блок с аргументами.

Например, если я называю [self showAViewWithOptions:4];, когда обратного вызова обожженных options = -1730451212.


Как связать значение options с блоком? Или лучше спросить, это просто невозможно, потому что, когда я звоню обратный вызов:

callback(); 

Я не прикладывая ничего в скобки?

Если это так, то хорошим последующим вопросом было бы: почему это даже скомпилировано в первую очередь?

+0

@trojanfoe, но где именно? Я знаю в JS, вы можете передать параметр блоку, привязывая его в конце так: 'function (parameter) {// Do stuff} (boundVariable);' но я не знаю, как сделать что-то вроде этого в Objective C. – David

+0

Я беру этот комментарий назад. Я дал ответ и верю, что он сработает. – trojanfoe

ответ

3

Это должно работать:

- (void)showAViewWithOptions:(int)options 
{ 
    if(_oldViews != nil) 
    { 
     [self hideOldView:^(){ 
      // Recursion doesn't feel right; be careful! 
      // Why can't whatever is being done by this call be done 
      // within this block? 
      [self showAViewWithOptions:options]; 
     }]; 
     return; 
    } 

    //Show the new view 
} 
+0

О, правда? Мне не нужно связывать его? Это просто происходит прямо? – David

+0

№.Блоки имеют доступ ко всем переменным в пределах своей области в момент их создания. – trojanfoe

+0

Вы бы на это посмотрели. Оно работает. Вау. Я решил, что это будет очень похоже на то, как Javascript обрабатывает блоки. Виноват. Благодаря! – David

0

блок с возвращаемым значением и параметрами выглядит следующим образом:

^ return_type (parameter1_type parameter1_name, parameter2_type parameter2_name, ...) { 
do_stuff; 
}; 
0

вы можете передать vairable в метод ... метод обратного вызова вызова внутри методы:

- (void)hideOldViewWithId:(float)f callback:(void (^)(float f))callback{ 
    f = f + 2.0f; 
    callback(f); 
} 

, а затем вызвать

[self hideOldViewWithId:1.0f callback:^(float f) { 
    NSLog(@"callback with float: %f", f); 
}]; 
Смежные вопросы