Blocks理解:html
Blocks能够访问局部变量,可是不能修改数组
若是修改局部变量,须要加__block闭包
__block int multiplier = 7; int (^myBlock)(int) = ^(int num) { multiplier ++;//这样就能够了 return num * multiplier; };
二、若是局部变量是数组或者指针的时候只复制这个指针,两个指针指向同一个地址,block只修改指针上的内容。如:ui
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil]; NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1]; [mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){ [mArrayCount addObject:[NSNumber numberWithInt:[obj length]]]; }]; NSLog(@"%@",mArrayCount);
例子里面确实没有修改mArrayCount
这个局部变量啊。mArrayCount
是一个指针,指向一个可变长度的数组。在block里面,并无修改这个指针,而是修改了这个指针指向的数组。换句话说,mArrayCount
是一个整数,保存的是一块内存区域的地址,在block里,并无改变这个地址,而是读取出这个地址,而后去操做这块地址空间的内容。spa
这是容许的,由于声明block的时候其实是把当时的临时变量又复制了一份,在block里即便修改了这些复制的变量,也不影响外面的原始变量。即所谓的闭包。指针
可是当变量是一个指针的时候,block里只是复制了一份这个指针,两个指针指向同一个地址。因此,在block里面对指针指向内容作的修改,在block外面也同样生效。code
__weak __typeof(&*self)weakSelf =self; 等同于htm
__weak UIViewController *weakSelf =self;对象
为何不用__block 是由于经过引用来访问self的实例变量 ,self被retain,block也是一个强引用,引发循环引用,用__week是弱引用,当self释放时,weakSelf已经等于nil。blog
扩展:NSTimer注意避免循环引用的地方,须要找个合适的时机和地方来 invalidate timer
在引用计数的环境里面,默认状况下当你在block里面引用一个Objective-C对象的时候,该对象会被retain。当你简单的引用了一个对象的实例变量时,它一样被retain。可是被__block存储类型修饰符标记的对象变量不会被retain
注意:在垃圾回收机制里面,若是你同时使用__weak和__block来标识一个变量,那么该block将不会保证它是一直是有效的。 若是你在实现方法的时候使用了block,对象的内存管理规则更微妙:也是(__weak与__block区别:)
一、若是你经过引用来访问一个实例变量,self会被retain。
二、若是你经过值来访问一个实例变量,那么变量会被retain
__weak主要适用于避免循环引用 , 如何避免请见博文:http://www.cnblogs.com/MasterPeng/p/5311911.html