iOS Block简介

概述

Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block也是一种数据类型,它可以定义变量、做参数、作为返回值, Block是代码块,它可以保存一段代码,并且在需要的时候再调用.在iOS开发中,Block常被用于GCD、动画、排序、传值等的各类回调.

1.定义一个Block
	typedef 返回值类型(^block名称)(参数列表);
	//例如:
	//无返回值无参数
	void(^block)(void);
	//无返回值有参数
	void(^block)(NSString *params);
	//有返回值有参数
	int(^block)(NSString *params1,NSString *params2);//形参也可省略
2.赋值和调用
//声明
typedef void(^block)(NSString *params);
//属性
@property (nonatomic ,copy) block blockname;
//赋值
self.blockname = ^(NSString *params) {
    NSLog(@"%@",params);
};

//调用
self.blockname(@"我是Block");

Block赋值只是保存了这样一段代码,只有我们调用Block之后他才会执行保存的这样一段代码,通常block的声明和调用在一个类,赋值是在另一个类,然后完成两个类之间的传值或者其他逻辑关系.

3.Block内部访问变量
  • 1.Block访问外部变量的问题:

    1.Block代码块内部可以声明一个与外部变量名称相同的变量,在Block内部访问时,遵循就近原则.
    2.Block代码块内,可以取到全局变量和局部变量的值;
    3.在Block代码块内可以修改全局变量的值,但是不能修改局部变量的值;
    4.如果需要修改Block代码块外的局部变量的值,就要给这个局部变量使用__block修饰符.
    5.__block的其实就是将局部变量, 拷贝到了堆区, 所以作用域结束, 实际上block修改的只是堆区的备份.

    为什么系统不给Block内部修改栈区局部变量

    Block执行的时机并不仅仅是在局部变量生命周期的那段作用域中, 因为Block也是一个数据类型, 他可以被当做参数传递, 所以执行时, 可能局部变量已经不存在了, 因为栈区的数据, 在过其作用域就被销毁了.

4.block的存储位置

Block内部的代码决定了Block代码存在的区域

  • 不访问外部变量:存储在全局区(执行的代码存储在代码段);

  • 访问外部变量:

      MRC下: 栈区
      MAR+copy或ARC下:都存储在堆区(连执行的代码都存储在堆区,不存储在代码段)
    
    block为什么用copy, 因为在MRC下, 不用copy, 拥有局部变量的代码, 存储在栈区, 当作用域结束, block也因为作用域的原因, 被弹栈了, 也就是被销毁了. 如果使用了copy, 那么block就被copy 到堆区了, 所以MRC下使用copy, 可以解决此问题, ARC下自动copy到堆区, 不使用copy也行, 所以也可以使用strong修饰.
5.block的循环引用

block作为属性时,被类强持有,在block其内部又使用持有它的类时会造成循环引用,内存泄露.

//造成循环引用
self.blockname = ^(NSString *params) {
    NSLog(@"我是block-----%@",self);
};
//解决:
//1.ARC下使用 __weak
__weak typeof(self) weakSelf = self;
self.blockname = ^(NSString *params) {
	NSLog(@"我是block-----%@",weakSelf);
};

//2.MRC下使用 __block
__block typeof(self) blockSelf = self;
self.someBlock = ^(NSString *params) {
	NSLog(@"我是block-----%@",blockSelf);
};

block底层原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值