По какой причине компилятор не будет рассматривать каждую переменную как переменную __block? - PullRequest
5 голосов
/ 31 октября 2011

Какое повышение производительности компилятора (особенно компиляторов, которые использует XCode) не рассматривает каждую переменную как переменную __block? Я предполагаю, что должно быть что-то, я сомневаюсь, что во время концепции переменных __block было решено, что

 __block SelfClass * blockSelf = self;

хороший и удобный синтаксис.

Ответы [ 2 ]

4 голосов
/ 31 октября 2011

Цель блоков состояла в том, чтобы сделать как можно более автоматическим и прозрачным использование блоков с минимальным синтаксисом и заставить их «просто работать».

Переменные, отличные от ___, по умолчанию намного больше соответствуют понятию "замыкания", которое представляют блоки. Блок снимает состояние всех переменных, на которые ссылается блок, в момент выполнения выполнения над объявлением блока. Это включает в себя как копирование памяти / состояния, так и сохранение любых ссылок на объекты Objective C, захваченных в блоке.

__block эффективно нарушает инкапсуляцию состояния в блоке. Очень полезно, но требует ручного управления ссылками на объекты со стороны программиста.

т.е. блочные переменные, отличные от __b, чаще всего «работают», а переменные __block, и поэтому поведение по умолчанию было стремиться «просто работать».

На практике стоимость захвата состояния внутри блока обычно минимальна. Измеримое влияние на производительность приложения, как правило, редко, и это часто указывает на архитектурную проблему более глубокого характера. <Ч />

Если по:

 __block SelfClass * blockSelf = self;

Вы имеете в виду перекрестное произведение блоков и ARC? Да, это немного неудачно. Но компилятор также предупреждает об очень реальной проблеме, о которой вам нужно знать. Тем не менее, очевидно, что предпочтительнее обходное решение.

0 голосов
/ 31 октября 2011

Потому что __block может пережить разрушение стека.Это будет заметно только с переменными области видимости c ++:

{
    __block shared_ptr<A> ptr = make_shared(new A);
    self.some_block = ^(void){};
} // ptr will not be deleted until the block is destructed
{
   shared_ptr<A> ptr = make_shared(new A);
    self.some_block = ^(void){};
} // ptr will be deleted here

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...