文档章节

(iOS) __block和__weak认识

青卷三部
 青卷三部
发布于 2016/11/08 16:46
字数 1073
阅读 55
收藏 1

果然还是对最基础的知识了解不透彻,今天看一看iOS中的两个修饰符:_____block和_____weak 。也是做一下温习吧。

1、先说weak,<弱引用>

我们知道weak的使用,比如声明一个控件属性,就会用到weak。

看代码:<code>@property(nonatomic,weak)UILabel *label;</code>

当然这并不是说声明控件就一定使用weak,相反的我在手动创建控件是大多数会使用strong。但如果你比较细心的话,你会发现我们使用xib时,使用的却是weak这一属性。那问题来了,我们使用strong 和 weak 的时机是何时呢?咱们接着往下看。<!--more-->

从storyboard 或者xib上创建控件

  • 在控件放在view上的时候,已经形成了如下的引用关系,以UILabel为例:UIViewController->UIView->subView-> UILabel 然后你为这个UILabel声明一个weak属性

<code>@property(nonatomic,weak) IBOOutlet UILabel * label;</code>

相当于xib对这个label是强引用,你声明的属性对它是弱引用。

手动创建控件

  • a). 将控件声明成strong <code>@property(nonatomic,strong) UIlabel * label;</code>

那么你在实现这个控件时只需这样:

<pre></code>_label = [[UIlabel alloc]init]; [self.view addSubview:_label]</code></pre>

  • b). 将控件声明成weak <code>@property(nonatomic,weak) UIlabel * label;</code> 那么你在实现这个控件时需要这样:

<pre><code>UIlabel *label = [[UIlabel alloc]init]; _label = label; [self.view addSubview:_btn];</code></pre>

关于block循环引用的问题

由于block会复制外部的变量,所以如果不注意,就会造成循环引用。对于这种情况,需要将引用的一方变成weak,从而避免循环引用。 看代码:

<pre><code> 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; }]; </code></pre>


2、strong和weak的区别

  • strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。
  • weak:弱引用,不决定对象的存亡。即使一个对象被持有无数个弱引用,只要没有强引用指向它,那么还是会被清除。
  • strong和copy是用来修饰强引用的属性,weak 用来修饰弱引用的属性;
  • strong、weak 需要ARC支持才能使用,copy不需要ARC支持
  • strong与retain功能相似;weak与assign相似,只是当对象消失后weak会自动把指针变为nil;

3、关于__block

先看一段代码:<pre><code> @autoreleasepool { __block NSInteger value = 0; void (^block)(void) = ^{ value = 1; }; block(); NSLog(@"val = %ld", value); }</code></pre> 我们现在看着可能得不出什么结论,那么,我们再看下面的代码,为了直观,我以图片的形式呈现:

picture1:

picture2: 现在对比就明显了。

下面总结一下:

  • 1.__block对象在block中是可以被修改、重新赋值的。

  • 2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

  • 3.blocks可以访问局部变量,但是不能修改。 如果修改局部变量,需要加__block ,所以__block 是让修改外部变量的值.

  • 对于 block 外的变量引用,block 默认是将其复制到其数据结构中来实现访问的

const-non-local-variables

  • 对于用 __block 修饰的外部变量引用,block 是复制其引用地址来实现访问的

mutable-non-local-variables

4、__block 和 __weak修饰符的区别:

  • 1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。

  • 2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。

  • 3.__block对象可以在block中被重新赋值,__weak不可以。


链接:

谈Objective-C block的实现:

Blocks are Objective-C`s:

iOS开发-由浅至深学习block:

© 著作权归作者所有

共有 人打赏支持
青卷三部
粉丝 0
博文 8
码字总数 8364
作品 0
浦东
iOS工程师
Xcode ARC需要什么版本的环境支持

Mac OS X v10.6 和 v10.7 (64位应用) 的Xcode 4.2以上版本支持ARC,iOS 4 和 iOS 5 下ARC都能工作,但Weak不支持Mac OS X v10.6 和 iOS 4,所以要想在iOS 4下运行用ARC的程序,只能用strong。...

东方皓
2013/05/06
0
0
iOS查看屏幕帧数工具--YYFPSLabel

学习 YYKit 代码时,发现 ibireme 在项目里加入的一个查看当前屏幕帧数的小工具,效果如下: 挺实用,实现方法也很简单,但是思路特别棒。 这里是Demo: YYFPSLabel 这里我把这个小工具从 中...

yehot
2016/04/05
0
0
IOS 浅谈闭包block的使用

前言:对于ios初学者,block通常用于逆向传值,遍历等,会使用,但是可能心虚,会感觉block很神秘,那么下面就一起来揭开它的面纱吧。 ps: 下面重点讲叙了闭包的概念,常用的语法,以及访问变...

周雨奇
07/23
0
0
iOS使用Objective-c自定义cordova插件(二)

接上一章. 中还有其它的配置、、、以及配置文件. eg: 框架: <framework src="CFNetwork.frame" weak="true"/> plist文件: <resource-file src="src/ios/PushConfig.plist"/> 默认的info.plis......

Michaelyn
2017/10/23
0
0
iOS与JS交互之WKWebView-WKUIDelegate协议

级别:★★☆☆☆ 标签:「iOS与JS交互」「WKWebView与JS交互」「WKUIDelegate」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前端...

QiShare
09/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sourcetree 离线免注册登录安装教程

Sourcetree是一个优秀的git可视化管理工具,深受开发者喜爱Sourcetree官网,但是在安装时需要谷歌账户登录,需要翻qiang才可以,此一点一直被人们所诟病。今天本教程就为大家提供离线免登陆安...

QQZZFT
14分钟前
0
0
使用 PostgreSQL 解决一个实际的统计分析问题

使用 PostgreSQL 解决一个实际的统计分析问题作者:老农民(刘启华)Email: 46715422@qq.com 之前有个朋友扔给我一个奇葩需求,他们公司之前做了一批问卷调查,全部都是统一格式的excel...

新疆老农民
17分钟前
0
0
TypeScript基础入门之高级类型的映射类型

转发 TypeScript基础入门之高级类型的映射类型 高级类型 映射类型 一个常见的任务是将一个已知的类型每个属性都变为可选的: interface PersonPartial {    name?: string;    age?...

durban
32分钟前
0
0
Dubbo源码分析(6):Dubbo内核实现之基于SPI思想Dubbo内核实现

SPI接口定义 定义了@SPI注解 package com.alibaba.dubbo.common.extension; import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.an......

郑加威
32分钟前
0
0
RxJS的另外四种实现方式(后记)—— 同时实现管道和链式编程

目录 RxJS的另外四种实现方式(序) RxJS的另外四种实现方式(一)——代码最小的库 RxJS的另外四种实现方式(二)——代码最小的库(续) RxJS的另外四种实现方式(三)——性能最高的库 Rx...

一个灰
35分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部