Цель C: можно ли использовать блочную переменную только один раз? - PullRequest
0 голосов
/ 18 мая 2019

Предположим, мне нужно несколько "вызовов" блоков, например, цикл, в котором блок передается другой функции в каждой итерации.Нужно ли создавать новый экземпляр блока каждый раз, когда я вызываю функцию (как в примере 1), или я могу создать один экземпляр блока, который вызывается каждый раз (как в примере 2)?

//Example 1:
while(true){
    void (^block)(NSString* test)=^(NSString* test){
        //do something
    };
    [self callWithBlock: block];
}

//Example 2
void (^block)(NSString* test)=^(NSString* test){
    //do something
};
while(true){

    [self callWithBlock: block];
}

Он компилируется иВторой способ работает нормально, но я подозреваю, что любые проблемы с параллелизмом могут быть не сразу очевидны.

1 Ответ

4 голосов
/ 18 мая 2019

Вы можете вызывать блоки так часто, как вы хотите. Но вы должны быть осторожны с контекстом, который захватывается блоком.

Если у вас есть какие-либо значения, захваченные вашим блоком, имейте в виду, что, если вы не укажете их как __block переменные, они будут скопированы.

Так, например, этот код:

int anInteger = 42;

void (^testBlock)(void) = ^{
    NSLog(@"Integer is: %i", anInteger);
};

anInteger = 84;

testBlock();

напечатает 42, а не 84.

Если вы объявите anInteger как __block int anInteger = 42, хранилище будет совместно использовано, и код напечатает 84.

Итак, если у вас есть код, похожий на:

int foo = 42;

void (^block)(void) = ^{
    NSLog(@"%i", foo);
}
while (true) {
    block();
    foo++;
}

поведение будет отличаться от

int foo = 42;
while (true) {
    void (^block)(void) = ^{
        NSLog(@"%i", foo);
    }
    block();
    foo++;
}

Это также будет применяться к указателям и переменным NSObject при переназначении переменной, содержащей указатель или объект.

Чтобы узнать больше, посмотрите Работа с блоками из документации разработчика Apple.

...