Pull to refresh

Comments 8

UFO just landed and posted this here
Я не совсем понял в чем существенная разница между __NSStackBlock__ и __NSMallocBlock__. Вроде бы оба хранят ссылки на внешние объекты, тем самым увеличивая счетчик ссылок. В чем тогда смысл вызова copy?

И еще по поводу copy. Вы писали:
Однако если же послать блоку 'copy', то блок переместится в кучу (__NSMallocBlock__)
Он точно переместится? Вроде бы copy должен копировать?
typedef void (^EmptyBlock)();
void foo(EmptyBlock block) {
    NSLog(@"my class:%@, my ptr %p", [block class], &block);
    block = [block copy];
    NSLog(@"my class:%@, my ptr %p", [block class], &block);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int a = 1;
        foo(^{
            int b = a;
        });
    }
    return 0;
}

2015-12-01 07:36:25.293 block_testing[580:13262049] my class:__NSStackBlock__, my ptr 0x7fff5fbff758
2015-12-01 07:36:25.294 block_testing[580:13262049] my class:__NSMallocBlock__, my ptr 0x7fff5fbff758

Блок создает внутри себя константные локальные переменные и указатели того, что захватывает. Что при использовании объектов увеличит счетчик ссылок, по обычной для ARC логике (при копировании блока в кучу).

Тоесть если внутри блока используются объекты, то retain будет отправлен именно при перемещении в кучу
извините, не о том подумал в ответе

typedef int (^EmptyBlock)();
void foo(EmptyBlock block) {
    EmptyBlock mallocBlock = block;
    EmptyBlock mallocBlock1 = block;
    
    NSLog(@"my class:%@, ptr block = %p", [mallocBlock class], mallocBlock);
    NSLog(@"my class:%@, ptr block = %p", [mallocBlock1 class], mallocBlock1);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int a = 1;
        foo(^int{
            return a+5;
        });
    }
    return 0;
}

2015-12-01 08:03:08.840 block_testing[683:13269753] my class:__NSMallocBlock__, ptr block = 0x100111d00
2015-12-01 08:03:08.841 block_testing[683:13269753] my class:__NSMallocBlock__, ptr block = 0x100111d30

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

Мне кажется, или существует какой-то негласный закон, что статьи об одном и том же без новой информации должны публиковаться каждые пол года/год?
Подобных статей на хабре уже достаточно(Что бы не быть голословным: Хабрапоиск). Да и на остальных ресурсах есть куча статей про блоки. Вы не внесли никакой новой информации в свою статью.
Так же по заголовку статьи, я ожидал увидеть о том, как работают блоки, а не как с ними работать. Слишком поверхностно описали блоки.

Например, сразу же возникают следующие вопросы: Что же есть стек хранения блоков, где он находится? Когда умирают блоки в стеке и какой их жизненный цикл в общем? Что есть куча? Какое её отличие от стека? Когда умирают глобальные блоки? Какой их жизненный цикл?
Спасибо большое за замечание и особенно за вопросы (не сарказм)
Постараюсь написать продолжение (по вопросам) через пол года/год в таком случае и обещаю чаще пользоваться хабропоиском перед публикацией )
Blocks ABI опушен, а это самый сок. Тема не раскрыта :) ведь блоки нужны для того, чтобы их вызывать, а как они вызываются вы не описали.

ЗЫ: советую помимо документации силанга посмотреть исходники, там больше информации можно почерпнуть.
__block все же может увеличивать счетчик ссылок на объект.
Sign up to leave a comment.

Articles