关于block的一点思考--底层可否用全局保存上层传下来的block
来源:互联网 发布:做一个软件多少钱 编辑:程序博客网 时间:2024/04/29 16:25
关于block的一点思考
上层传下来的block,用全局保存,那么上层可以嵌套这个block吗?
block在执行中又对全局block重新赋值,会出现什么问题吗,为什么?
以下demo,BlockTest模拟底层提供api,
fun1: Block: 模拟api接收block入参并保存block副本,
底层处理完事情后,执行保存在全局的block
测试方法中,block执行过程中又调用了BlockTest的fun1: block:方法
这时底层全局block还没执行完,又被自身在执行过程中赋值上新的block
赋值之后还没执行完的block是否能正常继续执行呢?
.h文件
#import <Foundation/Foundation.h>
typedefint(^TestBlock)(int p1);
@interface BlockTest :NSObject
-(int)fun1:(int)p1 Block:(TestBlock)block;
@end
.m文件
#import "BlockTest.h"
staticTestBlock testBlock;
static int gp1;
@implementation BlockTest
-(int)fun1:(int)p1 Block:(TestBlock)block
{
NSLog(@"begin fun1 P1=%d thread=%@",p1,[NSThreadcurrentThread]);
gp1 = p1;
testBlock = [block copy];
//底层尝试用3种方式来执行block
// [self performSelectorInBackground:@selector(ExcuteBlock) withObject:nil];
[selfperformSelector:@selector(ExcuteBlock)withObject:nilafterDelay:0.1];
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),/* dispatch_get_main_queue(),*/ ^{
// [self ExcuteBlock];
// });
NSLog(@"end fun1 P1=%d ",p1);
return 0;
}
-(void)ExcuteBlock
{
NSLog(@"befor testBlock p1=%d thread=%@",gp1,[NSThreadcurrentThread]);
testBlock(gp1);//如果有嵌套,那么这句在执行过程中会把自身给替换掉,这时替换语句后面的代码,以及下面的代码是否能正常继续运行
NSLog(@"after testBlock p1=%d thread=%@",gp1,[NSThreadcurrentThread]);
}
-(void)dealloc{
NSLog(@"dealloc %@",self);
}
@end
测试方法
-(void)testNestedGlobalBlock
{
BlockTest * blockTest = [[BlockTestalloc] init];
[blockTestfun1:1 Block:^int(int p1) {
NSLog(@"begin block 1");
NSLog(@"即将替换掉当前执行的block");
[blockTestfun1:2 Block:^int(int p1) {
NSLog(@"begin block 2");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
NSLog(@"dispatch_after");
});
NSLog(@"end block 2");
return 2;
}];
NSLog(@"被替换后,block继续运行");
NSLog(@"end block 1");
return 1;
}];
NSLog(@"testNestedGlobalBlock over");
}
测试结果
底层模拟了3种方式来执行方法,从而执行block,下面是执行过程中的输出结果
从这3种输出结果来看,正在执行中得block,虽然其对应的全局变量被替换掉了,但却还能正常往下执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),/* dispatch_get_main_queue(),*/ ^{
[selfExcuteBlock];
});
2015-01-07 15:15:38.820 test[1278:36599] begin fun1 P1=1 thread=<NSThread: 0x7ffa0b42ee20>{number = 1, name = main}
2015-01-07 15:15:38.821 test[1278:36599] end fun1 P1=1
2015-01-07 15:15:38.821 test[1278:36599] testNestedGlobalBlock over
2015-01-07 15:15:39.852 test[1278:36676] befor testBlock p1=1 thread=<NSThread: 0x7ffa0b768190>{number = 2, name = (null)}
2015-01-07 15:15:39.852 test[1278:36676] begin block 1
2015-01-07 15:15:39.853 test[1278:36676]即将替换掉当前执行的block
2015-01-07 15:15:39.853 test[1278:36676] begin fun1 P1=2 thread=<NSThread: 0x7ffa0b768190>{number = 2, name = (null)}
2015-01-07 15:15:39.854 test[1278:36676] end fun1 P1=2
2015-01-07 15:15:39.854 test[1278:36676]被替换后,block继续运行
2015-01-07 15:15:39.855 test[1278:36676] end block 1
2015-01-07 15:15:39.855 test[1278:36676] after testBlock p1=2 thread=<NSThread: 0x7ffa0b768190>{number = 2, name = (null)}
2015-01-07 15:15:40.866 test[1278:36676] befor testBlock p1=2 thread=<NSThread: 0x7ffa0b768190>{number = 2, name = (null)}
2015-01-07 15:15:40.866 test[1278:36676] begin block 2
2015-01-07 15:15:40.867 test[1278:36676] end block 2
2015-01-07 15:15:40.868 test[1278:36676] after testBlock p1=2 thread=<NSThread: 0x7ffa0b768190>{number = 2, name = (null)}
2015-01-07 15:15:40.868 test[1278:36676] dealloc <BlockTest: 0x7ffa0b527180>
2015-01-07 15:15:40.977 test[1278:36599] dispatch_after
[selfperformSelectorInBackground:@selector(ExcuteBlock)withObject:nil];
2015-01-07 15:15:14.735 test[1263:36135] begin fun1 P1=1 thread=<NSThread: 0x7ffb10d21c80>{number = 1, name = main}
2015-01-07 15:15:14.737 test[1263:36135] end fun1 P1=1
2015-01-07 15:15:14.737 test[1263:36135] testNestedGlobalBlock over
2015-01-07 15:15:14.738 test[1263:36218] befor testBlock p1=1 thread=<NSThread: 0x7ffb10c16940>{number = 2, name = (null)}
2015-01-07 15:15:14.738 test[1263:36218] begin block 1
2015-01-07 15:15:14.738 test[1263:36218]即将替换掉当前执行的block
2015-01-07 15:15:14.739 test[1263:36218] begin fun1 P1=2 thread=<NSThread: 0x7ffb10c16940>{number = 2, name = (null)}
2015-01-07 15:15:14.739 test[1263:36219] befor testBlock p1=2 thread=<NSThread: 0x7ffb10e8a170>{number = 3, name = (null)}
2015-01-07 15:15:14.740 test[1263:36219] begin block 2
2015-01-07 15:15:14.740 test[1263:36219] end block 2
2015-01-07 15:15:14.740 test[1263:36219] after testBlock p1=2 thread=<NSThread: 0x7ffb10e8a170>{number = 3, name = (null)}
2015-01-07 15:15:14.741 test[1263:36218] end fun1 P1=2
2015-01-07 15:15:14.741 test[1263:36218]被替换后,block继续运行
2015-01-07 15:15:14.742 test[1263:36218] end block 1
2015-01-07 15:15:14.838 test[1263:36218] after testBlock p1=2 thread=<NSThread: 0x7ffb10c16940>{number = 2, name = (null)}
2015-01-07 15:15:14.838 test[1263:36218] dealloc <BlockTest: 0x7ffb10c16c10>
2015-01-07 15:15:14.841 test[1263:36135] dispatch_after
[selfperformSelector:@selector(ExcuteBlock)withObject:nilafterDelay:0.1];
2015-01-07 15:14:12.868 test[1243:35475] begin fun1 P1=1 thread=<NSThread: 0x7ff481c287f0>{number = 1, name = main}
2015-01-07 15:14:12.869 test[1243:35475] end fun1 P1=1
2015-01-07 15:14:12.870 test[1243:35475] testNestedGlobalBlock over
2015-01-07 15:14:12.971 test[1243:35475] befor testBlock p1=1 thread=<NSThread: 0x7ff481c287f0>{number = 1, name = main}
2015-01-07 15:14:12.972 test[1243:35475] begin block 1
2015-01-07 15:14:12.972 test[1243:35475]即将替换掉当前执行的block
2015-01-07 15:14:12.972 test[1243:35475] begin fun1 P1=2 thread=<NSThread: 0x7ff481c287f0>{number = 1, name = main}
2015-01-07 15:14:12.972 test[1243:35475] end fun1 P1=2
2015-01-07 15:14:12.972 test[1243:35475]被替换后,block继续运行
2015-01-07 15:14:12.972 test[1243:35475] end block 1
2015-01-07 15:14:12.972 test[1243:35475] after testBlock p1=2 thread=<NSThread: 0x7ff481c287f0>{number = 1, name = main}
2015-01-07 15:14:13.075 test[1243:35475] befor testBlock p1=2 thread=<NSThread: 0x7ff481c287f0>{number = 1, name = main}
2015-01-07 15:14:13.075 test[1243:35475] begin block 2
2015-01-07 15:14:13.075 test[1243:35475] end block 2
2015-01-07 15:14:13.076 test[1243:35475] after testBlock p1=2 thread=<NSThread: 0x7ff481c287f0>{number = 1, name = main}
2015-01-07 15:14:13.076 test[1243:35475] dealloc <BlockTest: 0x7ff481d49540>
2015-01-07 15:14:13.180 test[1243:35475] dispatch_after
不过与其在那边担心用全局block会不会有问题,还不如做成局部的,那就不会有问题了吧,
下面这个demo,把block做成类的一个属性
.h文件
#import <Foundation/Foundation.h>
typedefint(^TestBlock)(int p1);
@interface BlockTest2 :NSObject
@property(nonatomic,copy)TestBlock testBlock;
-(int)fun1:(int)p1 Block:(TestBlock)block;
@end
.m文件
#import "BlockTest2.h"
static int gp1;
@implementation BlockTest2
-(int)fun1:(int)p1 Block:(TestBlock)block
{
NSLog(@"begin fun1 P1=%d thread=%@",p1,[NSThreadcurrentThread]);
gp1 = p1;
self.testBlock = block;
//底层尝试用3种方式来执行block
// [self performSelectorInBackground:@selector(ExcuteBlock) withObject:nil];
// [self performSelector:@selector(ExcuteBlock) withObject:nil afterDelay:0.1];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC)),dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),/* dispatch_get_main_queue(),*/ ^{
[selfExcuteBlock];
});
NSLog(@"end fun1 P1=%d ",p1);
return 0;
}
-(void)ExcuteBlock
{
NSLog(@"befor testBlock p1=%d thread=%@",gp1,[NSThreadcurrentThread]);
self.testBlock(gp1);
NSLog(@"after testBlock p1=%d thread=%@",gp1,[NSThreadcurrentThread]);
}
-(void)dealloc{
NSLog(@"dealloc %@",self);
}
@end
测试方法
-(void)testNestedMemberBlock
{
BlockTest2 * blockTest = [[BlockTest2alloc] init];
[blockTestfun1:1 Block:^int(int p1) {
NSLog(@"begin block 1");
BlockTest2 * blockTest1 = [[BlockTest2alloc] init];
[blockTest1fun1:2 Block:^int(int p1) {
NSLog(@"begin block 2");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
NSLog(@"dispatch_after");
});
NSLog(@"end block 2");
return 2;
}];
NSLog(@"end block 1");
return 1;
}];
NSLog(@"testNestedMemberBlock over");
}
测试结果
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC)),dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),/* dispatch_get_main_queue(),*/ ^{
[selfExcuteBlock];
});
2015-01-07 15:10:50.435 test[1178:33136] begin fun1 P1=1 thread=<NSThread: 0x7feb21e25810>{number = 1, name = main}
2015-01-07 15:10:50.436 test[1178:33136] end fun1 P1=1
2015-01-07 15:10:50.436 test[1178:33136] testNestedMemberBlock over
2015-01-07 15:10:51.516 test[1178:33228] befor testBlock p1=1 thread=<NSThread: 0x7feb21d65e40>{number = 2, name = (null)}
2015-01-07 15:10:51.516 test[1178:33228] begin block 1
2015-01-07 15:10:51.517 test[1178:33228] begin fun1 P1=2 thread=<NSThread: 0x7feb21d65e40>{number = 2, name = (null)}
2015-01-07 15:10:51.518 test[1178:33228] end fun1 P1=2
2015-01-07 15:10:51.518 test[1178:33228] end block 1
2015-01-07 15:10:51.518 test[1178:33228] after testBlock p1=2 thread=<NSThread: 0x7feb21d65e40>{number = 2, name = (null)}
2015-01-07 15:10:51.519 test[1178:33228] dealloc <BlockTest2: 0x7feb21d6cae0>
2015-01-07 15:10:52.577 test[1178:33228] befor testBlock p1=2 thread=<NSThread: 0x7feb21d65e40>{number = 2, name = (null)}
2015-01-07 15:10:52.577 test[1178:33228] begin block 2
2015-01-07 15:10:52.578 test[1178:33228] end block 2
2015-01-07 15:10:52.578 test[1178:33228] after testBlock p1=2 thread=<NSThread: 0x7feb21d65e40>{number = 2, name = (null)}
2015-01-07 15:10:52.579 test[1178:33228] dealloc <BlockTest2: 0x7feb21c2a000>
2015-01-07 15:10:52.688 test[1178:33136] dispatch_after
[selfperformSelectorInBackground:@selector(ExcuteBlock)withObject:nil];
2015-01-07 15:12:03.972 test[1201:34017] begin fun1 P1=1 thread=<NSThread: 0x7fb19870b040>{number = 1, name = main}
2015-01-07 15:12:03.973 test[1201:34017] end fun1 P1=1
2015-01-07 15:12:03.974 test[1201:34017] testNestedMemberBlock over
2015-01-07 15:12:03.974 test[1201:34093] befor testBlock p1=1 thread=<NSThread: 0x7fb198638ed0>{number = 2, name = (null)}
2015-01-07 15:12:03.974 test[1201:34093] begin block 1
2015-01-07 15:12:03.975 test[1201:34093] begin fun1 P1=2 thread=<NSThread: 0x7fb198638ed0>{number = 2, name = (null)}
2015-01-07 15:12:03.978 test[1201:34094] befor testBlock p1=2 thread=<NSThread: 0x7fb198418880>{number = 3, name = (null)}
2015-01-07 15:12:03.979 test[1201:34094] begin block 2
2015-01-07 15:12:03.979 test[1201:34094] end block 2
2015-01-07 15:12:03.979 test[1201:34094] after testBlock p1=2 thread=<NSThread: 0x7fb198418880>{number = 3, name = (null)}
2015-01-07 15:12:03.980 test[1201:34093] end fun1 P1=2
2015-01-07 15:12:03.980 test[1201:34093] end block 1
2015-01-07 15:12:03.981 test[1201:34093] dealloc <BlockTest2: 0x7fb198416ef0>
2015-01-07 15:12:03.981 test[1201:34093] after testBlock p1=2 thread=<NSThread: 0x7fb198638ed0>{number = 2, name = (null)}
2015-01-07 15:12:04.030 test[1201:34093] dealloc <BlockTest2: 0x7fb198641a50>
2015-01-07 15:12:04.084 test[1201:34017] dispatch_after
[selfperformSelector:@selector(ExcuteBlock)withObject:nilafterDelay:0.1];
2015-01-07 15:13:07.607 test[1225:34701] begin fun1 P1=1 thread=<NSThread: 0x7f975971d4b0>{number = 1, name = main}
2015-01-07 15:13:07.608 test[1225:34701] end fun1 P1=1
2015-01-07 15:13:07.609 test[1225:34701] testNestedMemberBlock over
2015-01-07 15:13:07.708 test[1225:34701] befor testBlock p1=1 thread=<NSThread: 0x7f975971d4b0>{number = 1, name = main}
2015-01-07 15:13:07.709 test[1225:34701] begin block 1
2015-01-07 15:13:07.709 test[1225:34701] begin fun1 P1=2 thread=<NSThread: 0x7f975971d4b0>{number = 1, name = main}
2015-01-07 15:13:07.709 test[1225:34701] end fun1 P1=2
2015-01-07 15:13:07.709 test[1225:34701] end block 1
2015-01-07 15:13:07.709 test[1225:34701] after testBlock p1=2 thread=<NSThread: 0x7f975971d4b0>{number = 1, name = main}
2015-01-07 15:13:07.709 test[1225:34701] dealloc <BlockTest2: 0x7f975952b180>
2015-01-07 15:13:07.811 test[1225:34701] befor testBlock p1=2 thread=<NSThread: 0x7f975971d4b0>{number = 1, name = main}
2015-01-07 15:13:07.811 test[1225:34701] begin block 2
2015-01-07 15:13:07.812 test[1225:34701] end block 2
2015-01-07 15:13:07.812 test[1225:34701] after testBlock p1=2 thread=<NSThread: 0x7f975971d4b0>{number = 1, name = main}
2015-01-07 15:13:07.813 test[1225:34701] dealloc <BlockTest2: 0x7f9759606310>
2015-01-07 15:13:07.917 test[1225:34701] dispatch_after
看起来执行也是没问题,且不用当心block被替换掉得问题,因为每次都是给一个新的对象赋值block属性
本来还当心BlockTest作为局部变量,会不会在block实际执行前就销毁了,不过看看日志,发现不会的,原因吗,我也不懂,真的发现自己是那么的无知
还有一点是,block在赋值时,用不用copy,区别在哪?
想多了解block,以下几篇文章可参考下
iOS Block在ARC/非ARC下的实用总结
http://www.tekuba.net/program/349/
【小测试】你真的知道blocks在Objective-C中是怎么工作的吗?(获奖公布)
http://www.cocoachina.com/bbs/read.php?tid=152222
iOS中Block介绍(一)基础
http://mobile.51cto.com/hot-403897.htm
iOS中Block介绍(二)内存管理与其他特性
http://mobile.51cto.com/hot-403914.htm
iOS中block介绍(三)揭开神秘面纱(上)
http://mobile.51cto.com/hot-403931.htm
iOS中block介绍(四)揭开神秘面纱(下)
http://mobile.51cto.com/hot-403935.htm
- 关于block的一点思考--底层可否用全局保存上层传下来的block
- 关于display:block的一点思考
- 对于block使用的一点思考
- block的底层实现
- 关于Java的一点感悟---底层开发者的上层学习感悟
- 关于底层的思考
- 关于Block的使用
- 关于block的应用
- 关于block的使用
- 关于block的基础
- 关于block的OC
- block 初探 关于block的用法
- block的底层实现(二)
- iOS中block实现的底层探究
- iOS中block实现的底层探究
- 关于 && 的一点思考
- 对iOS中block的一点领悟
- block回调的一点个人理解
- Ogre骨骼动画
- nopCommerce中文手册3
- SQLite学习手册(目录)
- 2015.1.12
- mir9-lua——《热血沙城》45度ARPG手游-Lua移植版
- 关于block的一点思考--底层可否用全局保存上层传下来的block
- TP 结构和材料之基本概念
- URL编码知识
- Java7之集合类型 ArrayList与Vector
- java.sql.Connection的close方法究竟干了啥(以MySQL为例)
- Android实用代码大全
- 自定义组件(第一)
- IOS学习资料整理【转】
- android Parcelable