Blocks是一个C Level的语法,以及一个运行时的特性,和标准C中的函数指针类似。
Blocks的声明:
int (^ Bfun) (int a)
相比的函数指针:
int (* Cfun) (int a)
Blocks的调用:
int (^ Bfun) (int a);
int inter = Bfun (100);
函数指针的调用:
int (* Cfun) (int a)
int inter = Cfun (100);
Blocks typedef定义
typedef int(^ SumBlockT ) (int a,int b);
C语言函数指针typedef定义
typedef int(* SumBlockT ) (int a,int b);
__Blocks关键字
一个Block内部是可以引用自身作用域之外的变量的,包括static变量,extern变量或自由变量(定义一个变量的时候,如果不加存储修饰符,默认情况下就是自由变量auto,auto保存在保存在stack中,除了auto之外,还存在register,static等修饰符),对于自由变量,Blocks是只读的,再引入Block是得同时,还引入一种特殊___block关键字变量存储修饰符。
下面介绍一个简单的Blocks的例子:
void (^myblocks) (void) = NULL;
myblocks = ^ (void) {
NSLog(@"in blocks");
};
myblocks();
__block int a = 0;//a变成全局变量
int (^ sum) (int c,int d) = ^(int c,int d){
a = c+d;
return a;
};
sum(10,30);
NSLog(@"a = %d",a);
typedef int (^ blockss) (int a,int b);blockss sunm = ^(int a,int b){
NSLog(@"add a and b:%d",a+b);
return 0;
};
sunm (13,45);
现在有如下代码:Person1.h
#import <Foundation/Foundation.h>
#import "dog2.h"
@interface Person1 : NSObject
{
dog2 *__dog;
}
@property (retain) dog2* dog; @end
Person1.m
#import "Person1.h"
@implementation Person1
@synthesize dog = __dog;
- (void) dealloc {
self.dog = nil;
}
-(void) setDog:(dog2 *)dog {
if (__dog != dog) {
__dog = dog ;
} //让狗知道调用哪个Blocks
[__dog setbarCall:^(dog2 *thisdog, int count) {
NSLog(@"Person dog %d count %d",[thisdog ID],count);//这个blocks变量存放于栈上 }];
}
@end
dog2.h
#import <Foundation/Foundation.h>
@interface dog2 : NSObject
{
int _ID;
int barCount;
NSTimer *timer; // 定义一个Blocks变量
void (^barkCall) (dog2 *thisdog,int count);
}
@property int ID; //给person1对象用得
- (void) setbarCall:(void (^) (dog2 *thisdog,int count))eachBark; //向外暴漏一个setbarCall:方法 @end
dog2.m
#import "dog2.h"
@implementation dog2
@synthesize ID = _ID;
-(void) dealloc { }
-(id) init {
self = [super init];
if (self) {
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];//每个1秒来调用[self updateTimer:nil]方法
};
return self;
}
-(void) updateTimer:(id) arg {
barCount ++;
NSLog(@"dog %d bar count %d",_ID,barCount); //给person1汇报一下 //需要调用person1里的Blocks
if(barkCall) {
barkCall (self,barCount);
}//调用从Person1传过来的Blocks
}
- (void) setbarCall:(void (^) (dog2 *thisdog,int count))eachBark {
barkCall = [eachBark copy];
}
@end
mian.m
#import <Foundation/Foundation.h>
#import "Person1.h" #import "dog2.h"
int main () {
@autoreleasepool {
Person1 *per = [[Person1 alloc] init];
dog2 *dog3 = [[dog2 alloc] init];
[dog3 setID:1];
[per setDog:dog3];
while (1) {
[[NSRunLoop currentRunLoop] run];
}
}
return 0;
}