对于block的理解

1、block跟swift中的闭包(closure)基本一样,都常用于值的回调,特别是在多线程的网络请求回调中,使用起来极为方便。

2、block的开头是“^”,接着是由小括号所报起来的参数列,行为主体由大括号包起来。block有四种类型,分别是无参无返回、无参有返回、有参有返回、以及有参无返回,而一般使用的block都是有参block,因为使用block主要就是进行参数的传递。

3、使用block时要特别注意类的循环引用,例如在一个控制器中,self强指针指向一个对象,而这个对象又强指针指向一个block,而在block中,又强指针指向了self,从而造成循环引用,导致内存无法释放,造成内存泄露。

4、解决循环应用的方法,常用__weak来打断强引用,例如用__weak来定义一个weakself来指向self的地址,如果self被释放,weakself指向的地址变为nil,从而打断引用环。需要注意的是,__weak是ARC专有的,__unsafe__unretained可以用在ARC,也可以用于MRC,但__unsafe__unretained是“assign”形式,如果指向的对象被释放,其指针地址保持不变,如果继续使用该指针,就会出现“野指针”。

5、关于block内存管理,当block内部没有引用外部变量时,block存放在全局区;在MRC下,当block内部引用外部变量时,block存放在栈区;当对该栈区的block进行copy操作时,block将存放在堆区。在ARC下,当block内部引用外部变量时,block存放在堆区;关于堆区与栈区的区别,栈区主要存放局部变量,定义的参数等,在函数结束,系统会自动回收其内存空间,而堆区一般用程序员自行分配释放,若程序员不释放,程序结束时,由系统回收。总的来说,使用栈区更为快捷,而使用堆区更为灵活。

6、如果要在block中修改外部变量,当变量是static全局变量时,block可以直接修饰,如果不是,可以用__block关键字来修饰,就可以在block内修改变量的值。

为什么在block内部无法修改外部的变量,尤其是栈区?

因为block大多数用来做数据传递,需要传递到其他地方调用执行,局部的变量在传递数据的时候容易丢失.

解决block循环引用方法

ARC: 解决block 循环引用问题使用__weak修饰self

MRC : 解决block 循环引用问题—— 使用__block

 

使用typed声明block

typedef void(^didFinishBlock) (NSObject *ob);

这就声明了一个didFinishBlock类型的block,

然后便可用

@property (nonatomic,copy) didFinishBlock  finishBlock;

声明一个block对象,注意对象属性设置为copy,接到block 参数时,便会自动复制一份。

__block是一种特殊类型,

使用该关键字声明的局部变量,可以被block所改变,并且其在原函数中的值会被改变。

 Block定义成属性为什么选择copy修饰符?

MRC : Block的本质是函数指针,内存地址在栈区,使用Copy是为了把Block由栈区拷贝到堆区,共享给当前对象使用.

ARC : Block定义成属性时,使用strong和copy的效果是一样,但是苹果官方建议使用copy.

 使用block和使用delegate完成委托模式有什么优点?

首先要了解什么是委托模式,委托模式在iOS中大量应用,其在设计模式中是适配器模式中的对象适配器,Objective-C中使用id类型指向一切对象,使委托模式在iOS中的实现更为方便。了解委托模式的细节:

使用block实现委托模式,其优点是回调的block代码块定义在委托对象函数内部,使代码更为紧凑;

适配对象不再需要实现具体某个protocol,代码更为简洁。

多线程与block

GCD与Block

使用 dispatch_async 系列方法,可以以指定的方式执行block

GCD编程实力

dispatch_async的完整定义

void dispatch_async(

dispatch_queue_t queue,

dispatch_block_t block);

功能:在指定的队列里提交一个异步执行的block,不阻塞当前线程

通过queue来控制block执行的线程。主线程执行前文定义的 finishBlock对象

dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();});

时间: 2024-10-27 05:55:47

对于block的理解的相关文章

对于block浅显理解

第一次接触block是在线程间通信. 一.简介block使用: 1.定义一个myBlock void (^myBlock)() = ^ { 2.定义block中需要执行内容 NSLog(@"--------Block中执行的内容"); } 3.执行block myBlock(); 一般情况这三步是分开进行的. *特殊处理 一般为防止没有给block中需要执行的内容赋值,一般做如下特殊处理 if(self.block) //首先判断block是否已经赋值 { self.block();

iOS开发中Block的理解与使用

简介 我们可以把Block当做Objective-C的匿名函数.Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观.另外,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息. block是代码块,其本质和变量类似.不同的是代码块存储的数据是一个函数体.使用Block,就可以像其他标准函数一样,传入参数,并得到返回值. block的格式: a:Block的返回值类型,可以为空(void); b:Block对象名称,可

关于Block的理解

代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 而且在iOS4之后,很多API都加入了Block作为参数适用,比如NSURLSessionDataTask中的complationHandler参数就是一个带有传入参数的block参数. block和一般的函数写法上区别不大,跟像是C/C++的函数写法,但唯一需要注意的是,在代码块外声明的变量,在block内是无法改变的,若想改变,必须加上  __bloc

Block内存管理实例分析

在ios开发中,相信说道block大家都不陌生,内存管理问题也是开发者最头疼的问题,网上很多讲block的博客,但大都是理论性多点,今天结合一些实例来讲解下. 存储域 首先和大家聊聊block的存储域,根据block在内存中的位置,block被分为三种类型: NSGlobalBlock NSStackBlock NSMallocBlock 从字面意思上大家也可以看出来 NSGlobalBlock是位于全局区的block,它是设置在程序的数据区域(.data区)中. NSStackBlock是位于

探索 Block (一) (Block 实现原理)

前言 要探索Block前先说一下我对Block的理解,我把它理解为:能够捕获它所在函数内部的变量的函数指针.匿名函数或者闭包.注意红色部份说的是它的精髓所在.希望看我这篇文章的人能够跟我说的步骤去做,做起来也比较简单,这样会有更好的效果,当然如果只看文章就能够让读者明白,那是我更加希望的. 一.首先,我们准备一个.m文件.我这里是main.m.内容如下: int main(int argc, char * argv[]) { void (^test)() = ^(){ }; test(); }

简单总结iNode和block知识

iNode:索引节点(index node) iNode是用来存储数据属性信息的,iNode包含的属性包括:文件大小.属组.归属的用户组.读写权限.文件类型.修改时间.还包括指向文件实体的指针功能(iNode节点和block的对应关系),但是,iNode不包括文件名. Block 是用来存储实际数据的. 理解:可以把iNode理解为一本书的目录,block理解为书的每一页. iNode小结: 1)磁盘分区格式化为ext4文件系统后会生成一定数量的iNode和block 2)iNode是索引节点,

Swift 05.Block

Swift的函数用法还真是灵活.但是个人感觉更灵活的还是闭包. swift闭包的概念大抵相当于OC的block的概念.如果对于block的理解很透彻的话,闭包的原理性的东西还是很好理解的. 剩下的就是灵活多变的用法了.在学习闭包之前,我还是想从新再总结一下block的原理和用法.毕竟闭包用好了真是简化了好多东西. ...今天总结完毕 block和闭包

IOS 面试 --- 动画 block

1 谈谈对Block 的理解?并写出一个使用Block执行UIVew动画? 答案:Block是可以获取其他函数局部变量的匿名函数,其不但方便开发,并且可以大幅提高应用的执行效率(多核心CPU可直接处理Block指令) [cpp] view plaincopyprint? [UIView transitionWithView:self.view duration:0.2 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^

深度理解依赖注入

1.依赖在哪里   老马举了一个小例子,是开发一个电影列举器(MovieList),这个电影列举器需要使用一个电影查找器(MovieFinder)提供的服务,伪码如下: 1/*服务的接口*/ 2public interface MovieFinder { 3    ArrayList findAll(); 4} 5 6/*服务的消费者*/ 7class MovieLister 8{ 9    public Movie[] moviesDirectedBy(String arg) {10