Блоки и переменные Objective-C
Сегодня я начал использовать блоки Objective-C. Я написал следующий код:
NSArray *array = @[@25, @"abc", @7.2];
void (^print)(NSUInteger index) = ^(NSUInteger index)
{
NSLog(@"%@", array[index]);
};
for (int n = 0; n < 3; n++)
print(n);
Который работает правильно. Мне нужно было изменить переменную array
после ее объявления, поэтому я попытался использовать следующий код:
NSArray *array;
void (^print)(NSUInteger index) = ^(NSUInteger index)
{
NSLog(@"%@", array[index]);
};
array = @[@25, @"abc", @7.2];
for (int n = 0; n < 3; n++)
print(n);
{[4] однако}, это не сработает. Консоль просто печатает (null)
три раза. Почему это не работает, в то время как это работало с моим первым фрагментом кода?
Примечание: я знаю, что это очень неэффективный способ просто печатать три значения моего массива, но это не мой исходный код. Я столкнулся с этой проблемой и попытался ее решить, чтобы понять, в чем она заключается.
2 ответа:
Это потому, что блок захватывает переменные по значению и при создании блока (Если вы не используете
__block
).То, что вы, вероятно, хотите:
NSArray *array = @[@25, @"abc", @7.2]; void (^print)(NSUInteger index) = ^(NSUInteger index) { NSLog(@"%@", array[index]); }; for (int n = 0; n < 3; n++) print(n);
Пример с
__block
:__block NSArray *array; void (^print)(NSUInteger index) = ^(NSUInteger index) { NSLog(@"%@", array[index]); }; array = @[@25, @"abc", @7.2]; for (int n = 0; n < 3; n++) print(n);
Обратите внимание, что это немного менее эффективно использовать
__block
, Если вам на самом деле не нужно изменять переменную внутри блока и отражать ее снаружи.