Block总结
来源:互联网 发布:淘宝上的开团提醒 编辑:程序博客网 时间:2024/05/16 05:55
block小结
定义:
1 Block是C语言的
2 Block是一个数据类型
3 是一个提前准备好的代码,在需要的时候执行
/** Block是C语言的 Block是一个数据类型 是一个提前准备好的代码,在需要的时候执行 */void demoBlock1();void demoBlock2();void demoBlock3();int main(int argc, const char * argv[]) { @autoreleasepool { demoBlock3(); } return 0;}void demoBlock3() { // 指针记录的是地址 NSMutableString *strM = [NSMutableString stringWithString:@"zhangsan"]; NSLog(@"定义前 %p %p", strM, &strM); void (^myBlock)() = ^ { // 修改strM指针指向的内容 [strM setString:@"lisi"]; NSLog(@"inblock %p %p", strM, &strM); // 这句代码是修改strM指针指向的地址// strM = [NSMutableString stringWithString:@"wangwu"]; }; NSLog(@"定义后 %p %p", strM, &strM); myBlock(); NSLog(@"%@", strM);}void demoBlock2() { // 使用 __block,说明不在关心x数值的具体变化 __block int x = 10; NSLog(@"定义前 %p", &x); // 栈区 // 如果要在block中,修改外部变量的数值,需要使用 __block 修饰符号 // 定义block时,如果引用了外部使用__block的变量,block定义之后,外部变量的指针地址同样会变成堆区的地址 void (^myBlock)() = ^ { x = 80; NSLog(@"in block %p", &x); // 堆区 }; NSLog(@"定义后 %p", &x); // 堆区 myBlock(); NSLog(@"%d", x);}
</pre><pre code_snippet_id="1656895" snippet_file_name="blog_20160421_3_7967570" name="code" class="objc">void demoBlock1() { int x = 10; NSLog(@"定义前 %p", &x); // 栈区 // 提问:输出是多少? // 在定义block的时候,如果引用了外部变量,会对外部变量做一个copy,记录住定义block时变量的数值 // 如果后续再修改x的值,不会影响block内部的数值变化! // 在默认情况下,不允许block内部修改外部变量的数值!因为会破坏代码的可读性,不易于维护! void(^myBlock)() = ^ { // x = 80; NSLog(@"%d", x); NSLog(@"in block %p", &x); // 堆中的地址 }; NSLog(@"定义后 %p", &x); // 栈区 x = 20; myBlock();}// block的定义void demo() { // block定义的速记符号 // inlineblock,能够快速敲出一个block的基本结构 // 提示:block的定义必须要过关! // 如果记不住,可以用inlineblock辅助记忆,不要依赖inlneblock // 定义block /** 定义时,把block当成数据类型 特点: 1. 类型比函数定义多了一个 ^ 2. 设置数值,有一个 ^,内容是 {} 括起的一段代码 最简单的定义方式 void (^myBlock)() = ^ { // 代码实现; } */ void (^myBlock)() = ^ { NSLog(@"hello"); }; // 执行时,把block当成函数 myBlock(); // 定义带参数的block // 格式:void (^block名称)(参数列表) = ^ (参数列表) { // 代码实现; } void (^sumBlock)(int, int) = ^ (int x, int y) { NSLog(@"%d", x + y); }; sumBlock(10, 20); // 定义带返回值的block // 格式:返回类型 (^block名称)(参数列表) = ^ 返回类型 (参数列表) { // 代码实现; } int (^sumBlock2)(int, int) = ^ int (int a, int b) { return a + b; }; NSLog(@"%d", sumBlock2(4, 8));}
// 如果要将block当作返回值,需要先单独定义一下block的类型// 速记符号:typedefBlocktypedef void(^workBlock)();使用block进行排序,效率非常高,以后替换掉for循环 // 1. 从iOS4开始,苹果封装了一系列块代码简化操作,提高效率 // 1> 使用块代码遍历,效率比for in要高 // 2> 把循环所需要的所有素材都以参数的形式提供了,可以直接使用 [array enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) { NSLog(@"%@", num); if (idx == 3) { *stop = YES; } }];排序(效率比正常排还要高) NSArray *result = [array sortedArrayUsingComparator:^NSComparisonResult(NSNumber *num1, NSNumber *num2) {// compare 可以比较NSString,NSDate,NSNumber... // 升序 return [num1 compare:num2]; // 降序 return [num2 compare:num1]; // 乱序,随机的顺序=》一会升序,一会降序 int seed = arc4random_uniform(2); if (seed == 1) { // 升序 return [num1 compare:num2]; } else { return [num2 compare:num1]; } }];
注意点:
一. block的反向传值
1. 调用方:准备块代码
跟"代理"来对比-类似于协议方法的实现
不同点:块代码都在一起,并没有单独的实现一个方法
2. 被调用方:执行块代码
1> 要执行的代码:在.h中定义一个块代码的属性,又被称作“回调方法”
2> 在需要的时候执行块代码!
1. 调用方:准备块代码
跟"代理"来对比-类似于协议方法的实现
不同点:块代码都在一起,并没有单独的实现一个方法
2. 被调用方:执行块代码
1> 要执行的代码:在.h中定义一个块代码的属性,又被称作“回调方法”
2> 在需要的时候执行块代码!
- 1 定义一个块代码的属性,block属性需要用copy
@property(nonatomic,copy)void(^completion)(NSString*text);
- 2 给目标视图控制器传值(准备执行的块代码)
// 目标视图控制器
CZEditViewController *vc = segue.destinationViewController;
vc.completion= ^ (NSString*str) {
self.nameLabel.text= str;
self.nameLabel.text= str;
};
- 3 在执行之前,先判断块代码属性是否有内容
if (self.completion) {
self.completion(self.nameText.text);
self.completion(self.nameText.text);
}
block陷阱
block的陷阱-有可能会出现循环引用
解决办法:
1. 要对内存对象之间的引用关系要清楚
技巧:
1. 在block中碰到self,要格外小心,“有可能”会出现循环引用,通常最好思考一下
2. 利用dealloc协助判断!如果不能被正常释放就说明有循环引用!
解决办法:
1. 要对内存对象之间的引用关系要清楚
技巧:
1. 在block中碰到self,要格外小心,“有可能”会出现循环引用,通常最好思考一下
2. 利用dealloc协助判断!如果不能被正常释放就说明有循环引用!
*** block在反向传值上有什么特点?
-简单
-所有代码都在一起,便于阅读,便于维护
*** block & delegate 如何选择?
-如果回调方法比较少,1~2,最好不要超过3个,这个时候使用block比较合适
-如果回调方法太多,会让代码显得臃肿,反而不好维护
-如果回调方法非常多,同时又不用每一个方法都必须实现,这个时候用delegate会比较方便!
-简单
-所有代码都在一起,便于阅读,便于维护
*** block & delegate 如何选择?
-如果回调方法比较少,1~2,最好不要超过3个,这个时候使用block比较合适
-如果回调方法太多,会让代码显得臃肿,反而不好维护
-如果回调方法非常多,同时又不用每一个方法都必须实现,这个时候用delegate会比较方便!
0 0
- block总结
- Block总结
- Block总结
- Block总结
- block总结
- BLOCK总结
- Block总结
- block总结
- Block总结
- Block 使用总结
- Block 简单总结
- iOS-block的总结
- 20141009(Block总结)
- inline-block总结
- iOS block 总结
- block的使用总结
- Block(高级)大总结
- iOS block使用总结
- HTML5 Web Worker的使用
- Intergraph CADWorx 2016下载 v16.0
- Linux内核基础--事件通知链(notifier chain)
- 冒泡排序java版
- NSNotificationCenter 的简单使用
- Block总结
- Kd-Tree算法原理和开源实现代码
- 机器学习 scikit-learn 图谱
- 欢迎使用CSDN-markdown编辑器
- sphinx教程2__安装、配置和使用
- 万年历api接口调用文档
- Intellij java: 未结束的字符串文字
- Qt-直接将xxx.ui文件转化为ui_xxx.h文件
- MySQL常用