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
0 0
原创粉丝点击