[IOS]关于Obeject C中block(块)的闲谈

1.关于Obeject C中block的使用语法

举例如下:

-(void) test{
	//声明一个返回值为long的,有两个入参且其中一个是long类型一个是bool类型的,名字叫做myblock的块
	long ^myblock(long,bool);
	//定义该block块
	myblock = ^(long i, bool flag){
		if(flag == true){
			NSLog("the number is:%d", i);
			return i;
		}else{
			NSLog("the number is:%d",i+1);
			return i+1;
		}
	}
	
	//直接调用块来使用
	long k = myblock(1.0, false);
	
	//或者作为其他函数的参数来使用
	[self functionWithBlock:myblock];
	//当作为其他函数参数来使用的时候,可以直接在调用的时候才进行声明定义
	[self functionWithBlock:^(long i, bool flag){
		if(flag == true){
			NSLog("the number is:%d", i+1);
			return i+1;
		}else{
			NSLog("the number is:%d",i+2);
			return i+2;
		}
	}]
}

-(void) functionWithBlock: (long (^)(long i, bool flag) block)
{
	//具体实现
	long i = 3;
	bool flag = true;
	block(i, flag);
}

2.当block中需要用到block外的变量的时候(注意这里的用到是指仅仅作为使用该值,而非进行修改),对于普通的block外的变量,那么block在定义的时候就会把这个变量拷贝一份至自己block块所对应的内存中作为一个常量,即使在外部这个变量后续变了,那么block内所用到的这个变量也一直不变,但是若这个外部变量是static修饰,则block块不会拷贝,而是直接用该值,即后续外部这个变量后续变了,那么block内所用到的这个变量也会跟着改变,举例如下:

-(void) test{
	long arg = 1.0;
	long normalOutV = 5;
	static long staticOutV = 5;
	__block long blockOutV = 5;
	
	
	//声明一个返回值为long的,有一个入参且是long类型的,名字叫做myblock的块
	long ^myblock(long);
	//定义该block块
	myblock = ^(long i){
		NSLog("the normalOutV plus i is :%ld", normalOutV+i);
		NSLog("the staticOutV plus i is :%ld", staticOutV+i);
		NSLog("the blockOutV plus i is :%ld", blockOutV+i);
	}
	
	//第一次调用
	//第一次调用分别输出6,6,6
	//????block修饰的block外的变量具体怎样没验证过..只是猜测...
	myblock(arg);
	
	//修改外部变量的值
	normalOutV++;
	staticOutV++;
	blockOutV++;
	
	//修改后第二次调用
	//第二次调用分别输出6,7,7
	//????block修饰的block外的变量具体怎样没验证过..只是猜测...
	myblock(arg);
	
}

当block中需要修改block外变量的值的时候,需要将这个变量用block 修饰,不然将会报错,因为如前面所说,block用到block外的普通变量的时候,本质是拷贝一份值至自己内存空间作为一个常量存储,所以不允许修改,但是用block就代表了block内使用block外的那个变量时还是到其本身所在的内存区域去寻址.

-(void) test{
	long arg = 1.0;
	long normalOutV = 5;
	static long staticOutV = 5;
	__block long blockOutV = 5;
	
	
	//声明一个返回值为long的,有一个入参且是long类型的,名字叫做myblock的块
	long ^myblock(long);
	//定义该block块
	myblock = ^(long i){
		normalOutV+=i;//报错,编译通不过
		staticOutV+=i;//这个不确定...有待验证...
		blockOutV+=i;//这个是正确的
	}	
}

3.关于block对象在内存中的位置,因为比较复杂,网上也有好多讲解,其实我自己本身听着也是模棱两可,所以这里就不做具体讲解,只是说几点我自己的理解:

首先,block代码块本质上可以看作是一种特殊的伪对象,为什么叫伪对象,因为正常来说,对象实际存在的内存是在堆中,但是像前面所举的几个block的例子,他们所对应的对象是在栈中的,随着test方法结束之后而自动被回收(注意,这里的回收跟ARC没有半毛钱关系),这种block被称为"NSStackBlock".但是如果把这个block对象执行了copy操作,那么copy之后返回的新block则是在堆中了,这个时候只能依靠release操作或者让ARC来自动回收内存空间了,这种block被叫做NSMallocBlock.看网上说还有一种block类型叫做NSGlobalBlock,说是当block里面没有局部变量的时候会block会变为这个类型,有点不理解,也不知道他到底是存在内存里哪个区域,静态区?还是别的..有待研究.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值