block基础

1. block基本概念

Block是C级别的语法和运行时特性。Block是一种比较特殊的数据类型,它可以保存一段代码,在合适的时候取出来调用。Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存、堆内存的引用。Block是苹果推荐的类型,效率高,可以帮助我们组织独立的代码段,并提高复用性和可读性。主要是用来在运行中封装代码和保存代码用的,Block可以在任何时候被执行。

从 xcode 4.0 开始,系统类库中的函数越来越多的开始使用 block 作为参数,以下是在系统函数中使用block的部分情况:a.遍历数组和字典b.排序c.视图动画d.结束回调e.错误处理f.多线程等

格式说明:(返回类型)(^块名称)(参数类型列表) = ^(形参列表) {代码实现};

如果没有参数,等号后面参数列表的()可以省略

2. 需要注意的地方

a. block(代码块)是 oc中的一种数据类型,可以被当做参数传递,可以有返回值,是一个能工作的代码单元,可以在任何需要的时候被执行,就像调用函数一样调用,在 ios 开发中广泛使用。

b. ^ 是 block 的特有的标记。

c. block  熟练了解block 的定义(块代码的定义),记得实现代码包含在 {} 之间。

d. block 是以内联 inline 函数的方式被定义使用。

e. 本质上是轻量级的匿名函数。

c. 块代码的使用注意点

   i. 默认情况下,不允许在块代码内部修改外部的变量的数值

   ii. __block,让外部的变量能够在block中修改

   iii. 循环引用的问题  __weak (ios5.0以下的版本使用__unsafe_unretained)

   iv. 默认情况下,block 外部的变量,在 block 中是只读的

  v. 块代码与代理的区别(代理和block是IOS上实现回调的两种机制。Block基本可以代替代理的功能,而且实现起来比较简洁,比较推荐能用block的地方不要用代理;单就编程过程而言,block对开发者处理逻辑,编程效率,代码阅读都有积极影响。代理是一种很经典的模式,我们很多人都已经习惯了这种模式,若果对block的回调传值的过程不是很理解的话,建议使用代理,可以达到同样地效果。)

3.block的修饰

   ARC情况下

1.如果用copy修饰Block,该Block就会存储在堆空间。则会对Block的内部对象进行强引用,导致循环引用。内存无法释放。

解决方法:新建一个指针(__weak typeof(Target) weakTarget = Target )指向Block代码块里的对象,然后用weakTarget进行操作。就可以解决循环引用问题。

2.如果用weak修饰Block,该Block就会存放在栈空间,不会出现循环引用问题。

  MRC情况下

用copy修饰后,如果要在Block内部使用对象,则需要进行(__block typeof(Target) blockTarget = Target )处理。在Block里面用blockTarget进行操作。

4.关于block引用外部变量操作的问题

block 使用,如果引用了外部变量,就会对外部变量做一个copy的操作,记录住定义block时候的值。如果后续再修改外部变量的值,不会影响block内部的数值的变化。

外部变量本来是在栈区中,block引用的那一刻,就将外部变量copy 到堆区中了,block里面使用的时copy 后堆中的变量的值。

所有在block 调用之前修改外部变量的值,不会影响block里面值的原因。

(如果要验证:可以通过打印地址值的方式来验证,栈区是高位地址值,相对于栈,堆在低位地址。通过打印地址发现,block里面的变量的地址值比block外面的地址值要小很多。)

在默认的情况下,是不允许在block内部修改外部变量的值。(原因是:会破坏代码的可读性,不易于维护)

如果我们一定要在block的内部修改外部变量的值,必须在外部变量的前面添加 _ _block ,这样才会允许修改。使用__block,说明不再关心外部变量数值的具体变化。

为什么使用__block 会达到这个效果(可以通过跟踪地址值发现问题)?

在定义block时,如果引用了外部变量使用了__block的变量。block定义之后,外部变量同样会被copy到堆中,不同的是栈中的那一份没有了,只保留了堆中的那一份。在block 中修改的那一份和保留的那一份是同一份,所以可以修改。

5.block的类型

block有几种不同的类型,这里列出常见的三种类型:

_NSConcreteGlobalBlock:全局的静态block,不会访问任何外部变量,不会涉及到任何拷贝,比如一个空的block。它既不在栈中,也不在堆中,我理解为它可能在内存的全局区。

_NSConcreteStackBlock:保存在栈中的block,当函数返回时被销毁。_NSConcreteStackBlock类型的block有闭包行为,也就是有访问外部变量,并且该block只且只有有一次执行,因为栈中的空间是可重复使用的,所以当栈中的block执行一次之后就被清除出栈了,所以无法多次使用。

_NSConcreteMallocBlock:保存在堆中的block,当引用计数为0时被销毁。该类型的block都是由_NSConcreteStackBlock类型的block从栈中复制到堆中形成的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容