__block __weak

IOS BLOCK收集

在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。 
Blocks的定义: 
         int (^Multiply)(int, int) = ^(int num1, int num2) {return num1 * num2;}; 
定义了一个Multiply的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现,注意{}blocks体里的;。 
Blocks可以访问局部变量,但是不能修改。 
              int multiplier = 7; 
     int (^myBlock)(int) = ^(int num) { 
         multiplier ++;//编译报错 
         return num * multiplier; 
     }; 
如果要修改就要加关键字:__block 
         __block int multiplier = 7; 
     int (^myBlock)(int) = ^(int num) { 
         multiplier ++;//这样就可以了 
         return num * multiplier; 
     };

...

在引用计数的环境里面,默认情况下当你在 block 里面引用一个 Objective-C 对象的时 候,该对象会被 retain。当你简单的引用了一个对象的实例变量时,它同样被 retain。 但是被__block 存储类型修饰符标记的对象变量不会被 retain. 注意:在垃圾回收机制里面,如果你同时使用__weak 和__block 来标识一个变量,那么该 block 将不会保证它是一直是有效的。

如果你在实现方法的时候使用了 block,对象的内存管理规则更微妙: 如果你通过引用来访问一个实例变量,self 会被 retain。
如果你通过值来访问一个实例变量,那么变量会被 retain。

 
dispatch_async(queue, ^{
 
// instanceVariable is used by reference, self is retained
 
doSomethingWithObject(instanceVariable);
 

});

 
 
 
id localVariable = instanceVariable;
 
dispatch_async(queue, ^{
 

// localVariable is used by value, localVariable is retained (not self)

 
doSomethingWithObject(localVariable);
 

});

拷贝Blocks

通常,你不需要 copy(或 retain)一个 block.在你希望 block 在它被声明的作用域 被销毁后继续使用的话,你子需要做一份拷贝。拷贝会把 block 移到堆里面。

你可以使用 C 函数来 copy release 一个 block:

如果你使用 Objective-C,你可以给一个 block 发送 copy、retain release(或 autorelease)消息。

为了避免内存泄露,你必须总是平衡 Block_copy()和 Block_release()。你必须平衡 copy retain release(或 autorelease)--除非是在垃圾回收的环境里面。

原文地址:https://www.cnblogs.com/ejllen/p/4220708.html