block为什么用copy?

2017-01-22  本文已影响44人  JanetDong

默认情况下,block是存档在栈中,可能被随时回收,需要copy操作。这也就是我们在定义block的时候用的是copy,而不是weak等等。

来看下面这个block定义:

// 默认是放在栈中,可能会被随时销毁

void (^blockName)() = ^{

};

// 进行一次copy操作,就可以放在堆中了。

// [blockName copy];

// 以下方法也一样。但是只能在非ARC中使用。

// Block_copy(blockName);

// 用retain没有用的原因:retain只是增加一次计数,block内存还是在栈中,并没有转移到堆中。

再看下面这个block使用:

Person *person = [[Person alloc] init];

person.blockName = ^{

   person.age = 20;

};

如果block是copy,并且里面使用它所在的类的对象的话,这个对象永远无法被释放。即person对象在堆中是强指针,且person在blockName就在,而blockName指向的代码也在堆中,即它的person.age=20的那些代码也在堆中,而这些代码中有person对象,所以又反过来指向person对象。就这么在相互指向的,永远不能释放。

解决方法,使用__weak修饰外部变量:

Person *person = [[Person alloc] init];

__weak Person *person0 = person;

person.blockName = ^{

   person0.age = 20;

};
上一篇 下一篇

猜你喜欢

热点阅读