首页 > 代码库 > 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初步认识