首页 > 代码库 > block初步认识

block初步认识

最近了解了一下block的应用 (其实早该掌握了 吐舌头) ,然后稍微整理了一下。

Block 是一个C Level的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从iOS4.0开始就很好的支持Block.

block的好处,主要1.用于回调特别方便, 2. 可以延长对象的作用区域。(__block关键字,将局部变量转变为全局变量)。但是block默认都是分配在stack上面的,即栈上面,所以它的作用区域就是当前函数。 

可以延长对象的作用域这块就不说了,主要说下用于回调。关于block用于回调这点,因为代理也可以实现其相同的功能。故我将block和delegate代理做了一下对比,发现,岂止相似,简直TMD相似.此处我举得例子是“狗和人的事情“,即看门狗发现敌情向人汇报。。

首先看block

定义两个类: Dog.h    Person.h

Dog.h

@interface Dog : NSObject

{

    int _ID;     //id编号

    NSTimer *timer;    //启动一个定时器

    int barkCount;    //狗叫的次数,也是向主人汇报的次数

    

    //定义一个blocks变量

    void (^BarkCallback) (Dog *thisDog,int count);

}

@property (assign)int ID;


//Person 用的

//向外暴露了一个函数  setBark

- (void) setBark:(void (^) (Dog *thisDog,int count)) eachBark;


@end


Dog.m:

#import "Dog.h"

@implementation Dog

//重写init方法,开启一个定时器,每隔1s向主人汇报情况

- (id)init

{

    self = [superinit];

    if (self) {

        timer = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTimer:)userInfo:nilrepeats:YES];

    }

    returnself;

}


- (void) updateTimer:(id)arg

{

    barkCount++;

    NSLog(@"dog %d bark count %d",_ID,barkCount);

        

    //Person/xiaoLi汇报一下 (进行通讯)

    //调用Person/xiaoLi里的blocks

    if (BarkCallback) {

        BarkCallback(self,barkCount);

    }    

}


- (void) setBark:(void (^) (Dog *thisDog,int count)) eachBark

{

    //从Person接收过来block

    BarkCallback = eachBark;

}


Person.h:

#import <Foundation/Foundation.h>

#import "Dog.h"


@interface Person : NSObject

@property (nonatomic,retain)Dog *dog;

@end



Person.m:

#import "Person.h"


@implementation Person

- (void)setDog:(Dog *)dog

{    

    [dog setBark:^(Dog *dog,int barkCount) {

        NSLog(@"Person, dog %d bark %d",dog.ID, barkCount);

    }];   

}

@end


在控制器里面调用:

     Dog *dog = [[Dogalloc] init];

    dog.ID = 10;

    

    Person *person = [[Personalloc] init];

    person.dog = dog;

跑一下程序,看打印:

2014-12-17 19:28:48.727 BlockDemo-2[2752:199621] dog 10 bark 1

2014-12-17 19:28:48.728 BlockDemo-2[2752:199621] Person, Dog 10 bark 1

2014-12-17 19:28:49.728 BlockDemo-2[2752:199621] dog 10 bark 2

2014-12-17 19:28:49.728 BlockDemo-2[2752:199621] Person, Dog 10 bark 2

2014-12-17 19:28:50.727 BlockDemo-2[2752:199621] dog 10 bark 3

2014-12-17 19:28:50.727 BlockDemo-2[2752:199621] Person, Dog 10 bark 3

......


 下面看下代理

同样:Dog.h:

#import <Foundation/Foundation.h>


@class Dog;


@protocol barkCallBack <NSObject>


- (void)barkCallBackToPerson:(Dog *)dog andCount:(int)barkCount;


@end


@interface Dog : NSObject

{

    int _ID;

    NSTimer *timer;

    int barkCount;

}


@property (assign) int ID;


@property (assign) id <barkCallBack> delegate;


@end


Dog.m:

#import "Dog.h"


@implementation Dog

- (instancetype)init

{

    self = [super init];

    if (self) {

        timer = [NSTimerscheduledTimerWithTimeInterval:1.0target:selfselector:@selector(updateTimer:)userInfo:nilrepeats:YES];

    }


    return self;

}


- (void)updateTimer:(id)arg

{

    barkCount++;

    NSLog(@"dog %d bark count %d",_ID,barkCount);

    if ([_delegate respondsToSelector:@selector(barkCallBackToPerson:andCount:)]) {

        [_delegatebarkCallBackToPerson:selfandCount:barkCount];

    }

}


@end


Person.h:

#import <Foundation/Foundation.h>

#import "Dog.h"


@interface Person : NSObject

@property (nonatomic,retain)Dog *dog;

@end


Person.m:

#import "Person.h"


@implementation Person


- (void) setDog:(Dog *)dog

{

    dog.delegate = (id)self;

}


- (void)barkCallBackToPerson:(Dog *)dog andCount:(int)barkCount

{

    NSLog(@"person  dog %d  bark %d",[dogID], barkCount);

}

@end


在控制器里:

    Person *xiaoLi = [[Personalloc] init];

    Dog *dog = [[Dogalloc] init];

    [dog setID:10];

    [xiaoLi setDog:dog];

    

    [[NSRunLoopcurrentRunLoop] run];   //此时,需要注意加上这句代码,不然程序会崩。不加也可以,但是要改其他地方。具体为什么,没弄懂,哈哈~~ 望高手赐教。

跑一下看看打印结果:

2014-12-17 19:53:35.092 DelegateDemo-Dog[3366:213877] dog 10 bark count 1

2014-12-17 19:53:35.093 DelegateDemo-Dog[3366:213877] person  dog 10  bark 1

2014-12-17 19:53:36.091 DelegateDemo-Dog[3366:213877] dog 10 bark count 2

2014-12-17 19:53:36.091 DelegateDemo-Dog[3366:213877] person  dog 10  bark 2

2014-12-17 19:53:37.092 DelegateDemo-Dog[3366:213877] dog 10 bark count 3

2014-12-17 19:53:37.092 DelegateDemo-Dog[3366:213877] person  dog 10  bark 3

......

一模一样


当然,你也可以在刚才的block程序里面或者delegate程序里面把Person.h去掉,直接在控制器里执行回调或者代理方法也行,让狗汇报情况。具体怎么实现都行。












block初步认识