__block 与 __weak的区别理解
Blocks理解:
Blocks可以访问局部变量,但是不能修改
如果修改局部变量,需要加__block
__block int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
multiplier ++;//这样就可以了
return num * multiplier;
};
2、如果局部变量是数组或者指针的时候只复制这个指针,两个指针指向同一个地址,block只修改指针上的内容。如:
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里,并没有改变这个地址,而是读取出这个地址,然后去操作这块地址空间的内容。
这是允许的,因为声明block的时候实际上是把当时的临时变量又复制了一份,在block里即使修改了这些复制的变量,也不影响外面的原始变量。即所谓的闭包。
但是当变量是一个指针的时候,block里只是复制了一份这个指针,两个指针指向同一个地址。所以,在block里面对指针指向内容做的修改,在block外面也一样生效。
__weak __typeof(&*self)weakSelf =self; 等同于
__weak UIViewController *weakSelf =self;
为什么不用__block 是因为通过引用来访问self的实例变量 ,self被retain,block也是一个强引用,引起循环引用,用__week是弱引用,当self释放时,weakSelf已经等于nil。
扩展:NSTimer注意避免循环引用的地方,需要找个合适的时机和地方来 invalidate timer
在引用计数的环境里面,默认情况下当你在block里面引用一个Objective-C对象的时候,该对象会被retain。当你简单的引用了一个对象的实例变量时,它同样被retain。但是被__block存储类型修饰符标记的对象变量不会被retain
注意:在垃圾回收机制里面,如果你同时使用__weak和__block来标识一个变量,那么该block将不会保证它是一直是有效的。 如果你在实现方法的时候使用了block,对象的内存管理规则更微妙:也是(__weak与__block区别:)
1、如果你通过引用来访问一个实例变量,self会被retain。
2、如果你通过值来访问一个实例变量,那么变量会被retain
+ (VideoChatBaseView*)loadViewFromNib:(Class)aClass; {
NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"VideoChatOverlapView" owner:nil options:nil];
__block VideoChatBaseView *view;
[array bk_all:^BOOL(id obj) {
if ([obj isKindOfClass:aClass]) {
view = (VideoChatBaseView*)obj;
return NO;
}
return YES;
}];
return view;
}
__block 与 __weak的区别理解的更多相关文章
- block(七)__block和__weak的区别-b
在MRC下,我们通常使用__block , 而在ARC下我们通常使用__weak , 或者__unsafe_unretaine __block(不安全,不建议使用) 来修饰对象防止循环引用而造成的内存 ...
- __block和__weak的区别
API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables ...
- __block 和 __weak的区别
Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock)(int) ...
- __Block与__Weak区别
一.__block理解: Blocks可以访问局部变量,但是不能修改, 声明block的时候实际上是把当时的临时变量又复制了一份, 在block里即使修改了这些复制的变量,也不影响外面的原始变量.即所 ...
- __block和__weak修饰符的区别
block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...
- __block 和__weak 区别及使用
API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables ...
- iOS __block 与 __weak
关于__block 与__weak http://stackoverflow.com/questions/19227982/using-block-and-weak 一下是一些区别的介绍 MRC: _ ...
- (iOS) __block和__weak认识
果然还是对最基础的知识了解不透彻,今天看一看iOS中的两个修饰符:__block和__weak .也是做一下温习吧. 1.先说weak,<弱引用> 我们知道weak的使用,比如声明一个控件 ...
- 区别assign VS weak,__block VS __weak
在objective-c中,类中的全局变量经常使用如下的方式申明. @property(nonatomic(1),strong(2))UIImageView *imageView; 其中的1,2处是对 ...
随机推荐
- A quick tour of JSON libraries in Scala
A quick tour of JSON libraries in Scala Update (18.11.2015): added spray-json-shapeless libraryUpdat ...
- bootstrap学习笔记之二
学习表单时还是有些吃力的,主要感觉有些结构有些复杂,没有自己亲手去操作就感觉似懂非懂,所以还得自己亲手测一下. 现在开始按钮的学习. 可作为按钮使用的标签和元素有: <a>.<bu ...
- webService 部署以后参数输入框不能显示
在<system.web> 标签下面加入这个 <system.web> <webServices> <protocols> <add name=& ...
- div自定义的滚动条 (水平导航条)
<!DOCTYPE html> <html> <head> <title></title> <style> div{ /* wi ...
- []with[[]]
[brand@localhost ~]$ echo $name hello hello [brand@localhost ~]$ [$name = "hello"] -bash: ...
- java之数组(笔记)
1.与c++不同的声明 int[] i, j; int i[], j; 这两种声明在c++中是同等的,但是在Java中,前者是声明两个,后者是只有i是数组. 2.数组可以看作是特殊的类 3.数组的cl ...
- IOS第15天(2,事件处理hitTest练习)
***hitTest 获取最合适的点 @implementation HMGreenView - (void)touchesBegan:(NSSet *)touches withEvent:(UIEv ...
- Otsu algorithm
一.介绍 OTSU算法也称最大类间差法,有时也称之为大津算法,被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用.它是按图像的灰度特性,将 ...
- 安卓中級教程(2):@InjectView中的對象inject
package com.example.ele_me.util; import java.lang.annotation.Annotation; import java.lang.reflect.Fi ...
- AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
在使用SqlConnection.Open()连接到SQL Server 2008 R2 SP2时,一直报以下异常: AccessViolationException: 尝试读取或写入受保护的内存.这 ...