Block的用法
来源:互联网 发布:js截取子字符串 编辑:程序博客网 时间:2024/06/05 07:11
1、Block的应用场景
对象与对象之间的通信方式。
2、 Block用法及和Delegate的区别:
Block:只有一个闭包,只能实现单一功能, 用Block能做到的大部分情况下代理都可以实现
Delegate:一个代理对象可以签署多个方法
(通知的通信方式是1对多;代理、Blocks是1对1。三种通信方式都实现了对象之间的解耦合)
3、Block的介绍
Block是IOS4.0之后新增的一种语法结构,也成为【闭包(closure)】;
SDK4.0新增的API大量使用了Block;
4、Block的使用
(1)声明(2)实现(3)调用
4.1、Block定义
//1.定义block //int (*p)(int, int); //caret,插入符 //返回值 (^block变量的名字)(参数列表) int (^block)(int, float); void (^block2)(int); //2.block赋值 //block = ^返回值 (参数列表 形参的名字){ // }; block = ^(int age, float height){ NSLog(@"block执行了"); return 0; }; block2 = ^void (int a){ }; //1.定义和2.赋值合并 void (^block3)(int) = ^(int age){ NSLog(@"age"); };//3.block调用 //回调 int result = block(23, 1.80); NSLog(@"result = %d", result);
4.2、通过typedef声明block类型
//typedef给一个已有的变量类型定义一个别名 //typedef <#returnType#>(^<#name#>)(<#arguments#>); //typedef 返回值 (^block的类型别名)(参数列表) typedef int (^MyBlock)(int, float);//typedef int MyInt;@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; int (^block1)(int age, float weight); //block1 //int (^)(int, float) //定义(声明)block MyBlock block2; block2 = ^(int age, float height){ return 0; }; block2(20, 1.7); [UIView animateWithDuration:1 animations:^{ ; }];}
4.3、block作为参数传递
#import "ViewController.h"typedef void(^MyBlock)(int, NSString *);@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //block赋值,作为参数传递给testBlock: [self testBlock:^(int age, NSString *name){ NSLog(@"age = %d, name = %@", age, name); }]; }//block作为参数传递给testBlock方法- (void)testBlock:(MyBlock)block{ block(20, @"张三");}@end
5. block和变量及内存管理
变量按作用域分为全局变量和局部变量
5.1引用局部变量时,该变量会作为常量编码到Block块中;局部变量需要使用__block修饰,才能在Block块中修改
typedef void(^MyBlock)(); int num = 10; MyBlock block = ^{ NSLog(@"%d",num); }; num = 20; block();
输出结果为10;
//添加__block修饰符,才可以修改 __block int num = 10; MyBlock block = ^{ NSLog(@"%d",num); }; num = 20; block();
输出结果为20;
Block调用局部基本数据类型对象,进入到Block里面,num会变成变量,如果添加了关键字__block,那么在Block里面num就是同一个变量,我们就可以修改(也可以替换成static关键字):
__block int num = 10;换成:static int num = 10;
5.2block引用局部对象,会retain该对象
NSObject *obj1 = [[NSObject alloc] init]; __block NSObject *obj2 = [[NSObject alloc] init]; MyBlock block = ^(int a){ NSLog(@"1----%@", obj1.retainCount); //obj1 retain 计数为2 NSLog(@"2----%@", obj2.retainCount); //obj2 计数为1 }; block(20); [obj1 release]; [obj2 release];
5.3、block里引用全局变量
NSLog(@"%ld", self.retainCount);//2 MyBlock block = ^(int a){ //block里引用全局变量,会把全局变量所在的对象retain num = 20; NSLog(@"%ld", self.retainCount);//3 };
Block本身可以像对象一样copy和release,Block创建后内存分在栈上,调用copy方法,会将Block从栈移到堆上。当Block声明为全局变量时,我们应该调用Block的copy方法。
//注意此处是copy@property(nonatomic, copy)NewBlock fBlock;
在Block(点语法)里面引用一个实例变量时,该实例对象会被retain,容易导致循环引用,循环用用会导致内存泄露。
6.Block的应用
将UIAlertView的按钮点击代理方法改为Block形式:
// ViewController.h#import <UIKit/UIKit.h>@interface ViewController : UIViewController<UIAlertViewDelegate>- (IBAction)buttonAction:(id)sender;@end----------// ViewController.m#import "ViewController.h"#import "BlockView.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}- (IBAction)buttonAction:(id)sender { BlockView *blockView = [[BlockView alloc] initWithTitle:@"title" message:@"message" cancelButtonTitle:@"cancel" otherButtonTitles:@"OK" clickBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { if (buttonIndex == 0) { NSLog(@"cancel"); }else { NSLog(@"OK"); } }]; [blockView show];}----------// BlockView.h#import <UIKit/UIKit.h>typedef void(^TouchBlock)(UIAlertView *alertView,NSInteger buttonIndex);@interface BlockView : UIAlertView@property(nonatomic, copy)TouchBlock block;- (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles clickBlock:(TouchBlock)block;@end----------// BlockView.m#import "BlockView.h"@implementation BlockView- (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles clickBlock:(TouchBlock)block { self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles, nil]; if (self) { self.block = block; } return self;}//点击按钮后执行的协议方法- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (self.block) { self.block(self, buttonIndex); }}@end
- iOS block的用法
- iOS block的用法
- iOS block的用法
- iOS block的用法
- Block的用法
- OC -- block的用法
- block的用法, 全局变量
- iOS block的用法
- iOS block的用法
- block的一些用法
- iOS block的用法
- iOS block的用法
- iOS block的用法
- iOS block的用法
- iOS block的用法
- iOS block的用法
- Block的用法
- iOS block的用法
- matlab dot函数
- memcached redis
- C语言——指针
- 判断两个链表是否有交点
- 源码阅读tinyhttpd
- Block的用法
- 第五周 阅读程序(6)
- js 获取html的select中的option的值
- sdut2610--Boring Counting(二分+划分树)
- console.dir()和console.log()的区别
- nodejs的require会寻找目录下默认的index文件,如果只提供目录路径的话
- 在Azure 环境里安装 SharePoint 2013 系统(二)附加磁盘和 安装SharePoint 2013
- 堆排序中求前K个最小数
- 【详细步骤】开启计算机远程桌面