block 学习笔记

1.block 用到的局部变量是 只读的,将关键字__block 定义局部变量 则变为可读写。

2.如果局部变量类型是 基本数据类型,比如NSinteger,那么block使用局部变量其实是其拷贝,类似于函数参数传值方式,所以在定义block之后修改局部变量对block代码块的内容没有影响。

	NSInteger outNum11 = 10; 
	NSInteger (^blockOne11)(NSInteger) = ^(NSInteger a){NSLog(@">>>%p %d",&outNum11,outNum11);  return outNum11+a;};
	outNum11 =5;
	NSLog(@">>>&outnum11=%p  %d",&outNum11,outNum11);
	NSLog(@">>>%d ",blockOne11(3));
输出结果,是13而不是8,从outNum11的地址指针也可以看出两者已经不同。

2012-09-02 11:33:51.606 TestBlockExample[984:f803] >>>&outnum11=0xbfffdcf4  5

2012-09-02 11:33:51.608 TestBlockExample[984:f803] >>>0xbfffdcec 10

2012-09-02 11:33:51.610 TestBlockExample[984:f803] >>>13 

 

3.如果局部变量类型是 NSobject类型,那么block使用局部变量,仍按函数参数传值方式,只是此时局部变量类型为指针,其值为指针所指对象地址,所以指针按值拷贝后仍指向相同的对象地址。

	NSMutableArray* outArray = [NSMutableArray arrayWithObjects:@"one",@"two",@"three", nil];
	
	NSMutableArray* (^blockOne)(NSMutableArray*) = ^(NSMutableArray* array){NSLog(@"\n>>>block %p %p %@",&outArray,outArray,outArray);[array removeLastObject]; return array;};
	[outArray removeObjectAtIndex:0];
	NSLog(@"\n>>>main %p %p  %@",&outArray,outArray,outArray);
	NSLog(@"\n>>>result%@  %p %p %@",blockOne(outArray),&outArray,outArray,outArray);

输出结果

2012-09-02 11:40:13.213 TestBlockExample[1072:f803] 
>>>main 0xbfffdcd4 0x6a2d4f0  (
    two,
    three
)
2012-09-02 11:40:13.213 TestBlockExample[1072:f803] 
>>>block 0xbfffdccc 0x6a2d4f0 (
    two,
    three
)
2012-09-02 11:40:13.214 TestBlockExample[1072:f803] 
>>>result(
    two
)  0xbfffdcd4 0x6a2d4f0 (
    two
)

4.若局部变量加上__block,则block内局部变量变为可读写,其实这时是类似于将原来使用的局部变量 按传值方式改为 传地址方式。

	__block NSInteger outNum11 = 10; 

	NSInteger (^blockOne11)(NSInteger) = ^(NSInteger a){NSLog(@">>>block %p %d",&outNum11,outNum11);  return outNum11+a;};
	
	outNum11 =5;
	NSLog(@">>>main =%p  %d",&outNum11,outNum11);
	NSLog(@">>>%d ",blockOne11(3));

输出结果,可以看到此时block中的局部变量地址没变
2012-09-02 11:49:08.557 TestBlockExample[1108:f803] >>>&outnum11=0xbfffdcf8  5
2012-09-02 11:49:08.559 TestBlockExample[1108:f803] >>>0xbfffdcf8 5
2012-09-02 11:49:08.560 TestBlockExample[1108:f803] >>>8 

局部变量为NSobject对象时

	__block NSMutableArray* outArray = [NSMutableArray arrayWithObjects:@"one",@"two",@"three", nil];
	
	NSMutableArray* (^blockOne)(NSMutableArray*) = ^(NSMutableArray* array){NSLog(@"\n>>>block %p %p %@",&outArray,outArray,outArray);[array removeLastObject]; return array;};
	[outArray removeObjectAtIndex:0];
	NSLog(@"\n>>>main %p %p  %@",&outArray,outArray,outArray);
	NSLog(@"\n>>>result%@  %p %p %@",blockOne(outArray),&outArray,outArray,outArray);

输出结果,

2012-09-02 11:55:43.666 TestBlockExample[1197:f803] 
>>>main 0xbfffdcf0 0x68b69e0  (
    two,
    three
)
2012-09-02 11:55:43.666 TestBlockExample[1197:f803] 
>>>block 0xbfffdcf0 0x68b69e0 (
    two,
    three
)
2012-09-02 11:55:43.667 TestBlockExample[1197:f803] 
>>>result(
    two
)  0xbfffdcf0 0x68b69e0 (
    two
)


 5.如果局部变量为static,则直接可以读写的,原因一样,因为是静态的,所以只有一份 

	static NSInteger outNum11 = 10; 

	NSInteger (^blockOne11)(NSInteger) = ^(NSInteger a){NSLog(@">>>block %p %d",&outNum11,outNum11);  outNum11=7; return outNum11+a;};
	
	outNum11 =5;
	NSLog(@">>>main =%p  %d",&outNum11,outNum11);
	NSLog(@">>>%d ",blockOne11(3));

输出结果:

2012-09-02 11:55:43.663 TestBlockExample[1197:f803] >>>main =0x4730  5
2012-09-02 11:55:43.665 TestBlockExample[1197:f803] >>>block 0x4730 5
2012-09-02 11:55:43.666 TestBlockExample[1197:f803] >>>10 

6.定义block 指针类似与 函数指针,可以作为 方法的参数

	NSInteger (^blockOne11)(NSInteger) = ^(NSInteger a){NSLog(@">>>block %p %d",&outNum11,outNum11);  outNum11=7; return outNum11+a;};

- (void)testBlock:(NSString*(^)(NSString*input))inputBlock
{
	NSLog(@">>>result=%@", inputBlock(@"kkk"));
}

7.block 也是继承与NSobject,block一般分配与stack,所以退出对应程序块时会自动释放,所以通过方法返回block时需要 对block指针做copy 在返回。

block与NSobject对象不同是,不能向block对象发送消息。

如果对block对象copy  则会自动对局部变量做retain(如果是NSObject),或拷贝到heap中(非NSobject对象)。另外,当局部变量使用了__block关键字,则不retain


8.如果block存取 类实例成员,不管通过存取器或直接访问成员,都会retain self 和该实例变量。





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值