iOS
来源:互联网 发布:关于养生之道的软件 编辑:程序博客网 时间:2024/05/22 09:38
Block 是一种苹果开发的基于 C 的调用方式,在 iOS 和 Mac 开发上都有广泛的应用。Block 从某种程度上来说是一种很新的回调方式,苹果在2009年将其引入 Mac OS X 10.6,之后在2010年将其引入到 iOS 4.0。
在iOS开发过程中,回调方式有三种Block、Delegate、NSNotification。这三种方式也是各有优缺点,这里只是讲一下Block的几种用法。什么东西都有优点和缺点,就像我除了帅就一无所有,所以的话,我们的Block也是一样的。
- Block的优点:方便、简单、快速回调、代码可读性强,尤其处理异步逻辑的时候让你爽的不要不要的。
- Block的缺点:
(1)由多个相关方法。假如每个方法都设置一个block,这样就会很麻烦,这时候就要考虑Delegate。Delegate让多个方法分成一组,只需要设置一次代理就可以完成多次回调。
(2)循环引用的问题,其实代理用strong修饰(上篇文章讲到的)也同样会有循环引用,但是block更容易产生!因为使用Block的时候稍微不注意可能就会导致对象是放不了,而且一旦出现就比较难检查出来,后果是毁灭性的。但是这个问题是我们完全可以避免的。
循环引用的解决方式就是,外部用__weak typeof(self) weakSelf = self; __weak修饰一下,使外部的self对象能够释放,在Block内部__strong typeof(self) self = weakSelf; __strong修饰一下,让内部能够拿到self对象就OK了。
第一种用法:作为属性传值
应用场景:比如界面之间反向传值
创建一个Person类
#import <Foundation/Foundation.h>/* typedef 定义一个blcok */typedef void (^block) (NSString * name,NSInteger age);@interface Person : NSObject@property (nonatomic,strong)block myBlock; //设置一个blcok属性@end
VC中的代码如下:
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import "ViewController.h"#import "Person.h"@interface ViewController ()/** */@property (nonatomic,strong) Person *p;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; Person * p = [[Person alloc]init]; //block 回调 p.myBlock = ^(NSString *name, NSInteger age) { NSLog(@"我的名字叫%@ 今年%ld岁了",name,age); }; _p = p;}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //block 传进两个参数 NSString * name = @"LY"; NSInteger age = 18; _p.myBlock(name, age);}
这样当我惦记屏幕的时候Block就会回调打印:
2017-06-29 14:08:51.070 BlockCircularReferenceDemo[4968:12856691] 我的名字叫LY 今年18岁了
第二种用法:作为方法的参数,主要是外界不能调用,只能在这个方法内部调用,用于回调合传值等。
应用场景:比如网络请求(AFN)
同样是Person类
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject-(void)run:(void(^)())runBlock;@end
-(void)run:(void(^)())runBlock{ NSLog(@"一起跑步吧!"); runBlock();}
VC里面的代码如下:
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import "ViewController.h"#import "Person.h"@interface ViewController ()/** */@property (nonatomic,strong) Person *p;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; Person * p = [[Person alloc]init]; [p run:^{ NSLog(@"跑完洗澡澡"); }];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
打印结果:
2017-06-29 15:12:52.742 BlockCircularReferenceDemo[5096:12936446] 一起跑步吧!2017-06-29 15:12:52.742 BlockCircularReferenceDemo[5096:12936446] 跑完洗澡澡
把Block作为参数,先执行-(void)run:(void(^)())runBlock;这个方法,等这个方法执行完之后就回调会VC里面的 NSLog(@”跑完洗澡澡”);这句代码。
第三种用法:作为方法的返回值,内部不能调用,只能外界调用。
应用场景:Masonry 的用法 ,链式编程的思想。
还是我们的Person类:
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject- (void(^)())run;@end
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import "Person.h"@implementation Person- (void(^)())run{ return ^(){ NSLog(@"跑了10圈了"); };}@end
VC代码如下:
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import "ViewController.h"#import "Person.h"@interface ViewController ()/** */@property (nonatomic,strong) Person *p;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; Person * p = [[Person alloc]init]; //直接用点语法调用run方法,很几把屌是不是! ()里面可以穿参数的呦! p.run();}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
打印:
2017-06-29 15:35:45.464 BlockCircularReferenceDemo[5263:12967469] 跑了10圈了
那么接下来,玩一个变态用法,链式编程用法:
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject//这个run方法的返回值是一个 block ,那么这个block的返回值是 - 方法的调用者 p 对象的类型 Person *- (Person *(^)(int a))run;@end
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import "Person.h"@implementation Person- (Person * (^)(int a))run{ //这个方法返回一个block return ^Person *(int a){ NSLog(@"跑了%d圈了",a); //block的返回值是 self (Person * 类型) return self; };}@end
// Created by cuzZLYues on 2017/6/28.// Copyright © 2017年 cuzZLYues. All rights reserved.//#import "ViewController.h"#import "Person.h"@interface ViewController ()/** */@property (nonatomic,strong) Person *p;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; Person * p = [[Person alloc]init]; /* 现在我传一个参数! p.run 这一步是一个get方法他的返回值是一个带参数的block,也就是这一坨: return ^Person *(int a){ NSLog(@"跑了%d圈了",a); //block的返回值是 self (Person * 类型) return self; }; p.run(10) 到了这一步,它的返回值就是一个Person对象,所以怎么样,我们能继续点语法一直点点点。。 p.run(10).run(19).run(20); */ p.run(10).run(19).run(20);}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
看到注释应该很清楚啦吧,这就是链式编程的思想,以上就是Block的几种玩法啦,希望大家多多支持一下,多多评论,我们互相交流和学习!
最后全部代码在这里:https://github.com/yueShenAAA/BlockUtilize
- iOS
- iOS
- IOS
- iOS
- iOS
- IOS
- ios
- iOS
- iOS
- IOS
- iOS
- ios
- ios ~~~~~
- ios
- IOS
- IOS
- IOS
- ios
- 解决 centos7 不能上网
- ArcGIS Desktop 10.2 安装与破解图文教程
- LeetCode 283. Move Zeroes
- PHP中的AES算法
- Neo4j初步学习
- iOS
- ueditor抓取文件配置
- FFmpeg架构之I/O模块分析——讲得还行,主要是架构
- sleep时间过长处理方法
- JS中使用"data-"开头的属性及data()方法实现自定义属性
- 读OkHttp3文档记录
- Scaling Memcache At Facebook
- RabbitMq(三)
- iOS NSFileManager管理目录路径(3)——文件大小