(iOS) __block和__weak认识
果然还是对最基础的知识了解不透彻,今天看一看iOS中的两个修饰符:__block和__weak 。也是做一下温习吧。
1、先说weak,<弱引用>
我们知道weak的使用,比如声明一个控件属性,就会用到weak。
看代码:
@property(nonatomic,weak)UILabel *label;
当然这并不是说声明控件就一定使用weak,相反的我在手动创建控件是大多数会使用strong。但如果你比较细心的话,你会发现我们使用xib时,使用的却是weak这一属性。那问题来了,我们使用strong 和 weak 的时机是何时呢?咱们接着往下看。
从storyboard 或者xib上创建控件
在控件放在view上的时候,已经形成了如下的引用关系,以UILabel为例:UIViewController->UIView->subView-> UILabel
然后你为这个UILabel声明一个weak属性
@property(nonatomic,weak) IBOOutlet UILabel * label;
相当于xib对这个label是强引用,你声明的属性对它是弱引用。
手动创建控件
a). 将控件声明成strong
@property(nonatomic,strong) UIlabel * label;
那么你在实现这个控件时只需这样:
_label = [[UIlabel alloc]init];
[self.view addSubview:_label]
b). 将控件声明成weak
@property(nonatomic,weak) UIlabel * label;
那么你在实现这个控件时需要这样:
UIlabel *label = [[UIlabel alloc]init];
_label = label;
[self.view addSubview:_btn];
关于block循环引用的问题
由于block会复制外部的变量,所以如果不注意,就会造成循环引用。对于这种情况,需要将引用的一方变成weak,从而避免循环引用。
看代码:
BlocksViewController *blockVC = [[BlocksViewController alloc]init];
__weak ViewController *weekSelf = self;
/**
* 1、使用弱引用来解决block循环引用问题
*
* 2、block能截取自动变量,并且是不能在block块中进行修改的(除非用 __block修饰符)这里的 weekSelf.textField.text 的值是被修改了,并且没有使用 __block修饰符。原因是因为textField是全局变量,如果定义一个局部变量,比如:定义个 “text”是不能被修改的,编译器会报错,
*/ //block回调传值
[blockVC returnValue:^(NSString *content) {
weekSelf.textField.text = content;
// text = content;//这里会提示错失__block;
}];
2、strong和weak的区别
a) strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。
b) weak:弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。
c)strong和copy是用来修饰强引用的属性,weak 用来修饰弱引用的属性;
d)strong、weak 需要ARC支持才能使用,copy不需要ARC支持
e)strong与retain功能相似;weak与assign相似,只是当对象消失后weak会自动把指针变为nil;
3、关于__block
先看一段代码:
@autoreleasepool {
__block NSInteger value = ;
void (^block)(void) = ^{
value = ;
};
block();
NSLog(@"val = %ld", value);
}
我们现在看着可能得不出什么结论,那么,我们再看下面的代码,为了直观,我以图片的形式呈现:
现在对比就明显了。
下面总结一下:
a) 1.__block对象在block中是可以被修改、重新赋值的。
b)2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。
c)3.blocks可以访问局部变量,但是不能修改。
如果修改局部变量,需要加__block ,所以__block 是让修改外部变量的值.
对于 block 外的变量引用,block 默认是将其复制到其数据结构中来实现访问的
对于用 __block 修饰的外部变量引用,block 是复制其引用地址来实现访问的
4、__block 和__weak修饰符的区别:
1>.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2>.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3>.__block对象可以在block中被重新赋值,__weak不可以。
**链接:**
[谈Objective-C block的实现]<http://blog.devtang.com/2013/07/28/a-look-inside-blocks/>
[Blocks are Objective-C`s]<http://rypress.com/tutorials/objective-c/blocks>
[iOS开发-由浅至深学习block]<http://www.cnblogs.com/luoxiaofu/p/5445327.html>
(iOS) __block和__weak认识的更多相关文章
- iOS __block 与 __weak
关于__block 与__weak http://stackoverflow.com/questions/19227982/using-block-and-weak 一下是一些区别的介绍 MRC: _ ...
- __Block与__Weak区别
一.__block理解: Blocks可以访问局部变量,但是不能修改, 声明block的时候实际上是把当时的临时变量又复制了一份, 在block里即使修改了这些复制的变量,也不影响外面的原始变量.即所 ...
- __block和__weak的区别
API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables ...
- __block 和__weak 区别及使用
API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables ...
- block(七)__block和__weak的区别-b
在MRC下,我们通常使用__block , 而在ARC下我们通常使用__weak , 或者__unsafe_unretaine __block(不安全,不建议使用) 来修饰对象防止循环引用而造成的内存 ...
- __block和__weak修饰符的区别
block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...
- __block 和__weak
1,在MRC 时代,__block 修饰,可以避免循环引用:ARC时代,__block 修饰,同样会引起循环引用问题: 2,__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修 ...
- __block 和 __weak的区别
Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock)(int) ...
- __block 与 __weak的区别理解
Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock)(int) ...
随机推荐
- Mono-D在MacOS上的设置
1. 下载DMD 建议下载tar.xz压缩包,不建议下载dmg安装包,因为dmg中没有src,而后面需要用src中的内容设置代Code Completion. 地址:http://dlang.org/ ...
- AutofacContainer
/// <summary> /// Autofac容器 /// </summary> public class AutofacContainer { public static ...
- MySQL随机获取数据的方法,支持大数据量
最近做项目,需要做一个从mysql数据库中随机取几条数据出来. 总所周知,order by rand 会死人的..因为本人对大数据量方面的只是了解的很少,无解,去找百度老师..搜索结果千篇一律.特发到 ...
- JavaScript getComputedStyle
我们使用 element.style 也可以获取元素的CSS样式声明对象,但是其与 getComputedStyle 方法还是有一些差异的. 首先,element.style 是可读可写的,而 get ...
- codevs3163 抄书问题2
题目描述 Description 现在要把M本有顺序的书分给K个人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比 如不能把第一.第三. ...
- Coursera-Getting and Cleaning Data-week1-课程笔记
博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html -- Sunday, January 11, 2015 课程概述 G ...
- 试图加载格式不正确的程序。 (异常来自HRESULT:0x8007000B)
异常来自HRESULT:0x8007000B 缘由:在64位操作系统下IIS发布32位的项目,报“项目依赖的dll无法读取,试图加载格式不正确的程序”错误. 原因:程序集之间的通讯要么全是64位环 ...
- C#给其他程序发消息
1.相关声明函数,SendMessage可定义两种格式. [DllImport("User32.DLL", CharSet = CharSet.Auto)]public stati ...
- Java总结篇系列:Java多线程(一)
多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程 ...
- JS中的call()和apply()方法
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...