1.预定义Block
typedef void(^myblock1)(int a,int b);
2.将Block做为类的属性
@property(nonatomic,strong) myblock1 block1;
3.代码demo 在.h中声明了一个方法用于调用Block
#import <Foundation/Foundation.h>
typedef void(^myblock1)(int a,int b);
@interface Myblock : NSObject
@property(nonatomic,strong) myblock1 block1;
-(void)fun:(int) seta param1 :(int)setb;
@end
在.m中:
#import "block.h"
@implementation Myblock
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
-(void)fun:(int) seta param1 :(int)setb;
{
_block1(seta,setb);
}
@end
在main中:实例化类,并为作为属性的Block指明执行的方法
#import <Foundation/Foundation.h>
#import "block.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Myblock *myblock1=[[Myblock alloc]init];
myblock1.block1=^(int a,int b)
{
NSLog(@"%d",a+b);
};
[myblock1 fun:5 param1:5];
}
return 0;
}
OC中的Block类似C、C++的函数指针,C#的委托、匿名函数和Lambda,与其不同的是Block可以访问函数以外、词法作用域以内的外部变量的值。换句话说,Block不仅 实现函数的功能,还能携带函数的执行环境
Block对外部变量的存取管理
基本数据类型
1、局部变量
局部自动变量,在Block中只读。Block定义时copy变量的值,在Block中作为常量使用,所以即使变量的值在Block外改变,也不影响他在Block中的值。
{
int base = 100;
long (^sum)(int, int) = ^ long (int a, int b) {
return base + a + b;
};
base = 0;
printf("%ld\n",sum(1,2));
// 这里输出是103,而不是3, 因为块内base为拷贝的常量 100
}
2、STATIC修饰符的全局变量
因为全局变量或静态变量在内存中的地址是固定的,Block在读取该变量值的时候是直接从其所在内存读出,获取到的是最新值,而不是在定义时copy的常量.
{
static int base = 100;
long (^sum)(int, int) = ^ long (int a, int b) {
base++;
return base + a + b;
};
base = 0;
printf("%ld\n",sum(1,2));
// 这里输出是4,而不是103, 因为base被设置为了0
printf("%d\n", base);
// 这里输出1, 因为sum中将base++了
}
3、__BLOCK修饰的变量
Block变量,被__block修饰的变量称作Block变量。 基本类型的Block变量等效于全局变量、或静态变量。
注:BLOCK被另一个BLOCK使用时,另一个BLOCK被COPY到堆上时,被使用的BLOCK也会被COPY。但作为参数的BLOCK是不会发生COPY的
时间: 2024-09-23 13:07:30