How Do I Declare A Block in Objective-C?
As a local variable:
returnType(^blockName)(parameterTypes) = ^returnType(parameters) {
...};
As a property:
@property (nonatomic, copy,nullability)returnType(^blockName)(parameterTypes);
As a method parameter:
- (void)someMethodThatTakesABlock:(returnType(^nullability)(parameterTypes))blockName;
As anargument to a method call:
[someObject someMethodThatTakesABlock:^returnType(parameters) {
...}];
As atypedef:
typedef returnType(^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
11. Block
可对比指针函数
int sum(int a, int b)
int (^sum)(int, int) = ^(int a, int b) {};
typedef:定义类型别名
typedef int (^myBlock)(int, int);
myBlock不再是变量名,而是类型:
myBlock block = ^(int a, int b){};
block 内部访问外部变量 可以读取,但不是同一个内存地址, block访问的变量是在堆区,会把m从栈区拷贝到堆区。block对象也在堆区。所以也无法修改。
需要用block来修饰变量, 不在以const方式copy
int m =10;//可以访问,访问的是copy
__block int n = 10; // capture n in block?
void (^block)() = ^(){
n = 15;
};
修改全局变量不需要block
block 作为参数
参数用于执行,但不能修改,修改是执行参数时候要做的事情
定义的时候只能执行。执行的时候才能定义。(函数, block)
- (void) testBlock: (void (^)(int a))block;
- void normalDay(void(^work)()){
NSLog(@"get up!");
work();
NSLog(@"go home");
}
normalDay(
^{
NSLog(@"xxxx");
}
);
Block内存管理
强指针放到堆中。
MRC
ARC
- block没有引用外部变量,全局区
- block引用外部局部变量,就放到堆区(局部变量默认强指针,强指针默认放堆区)
Block循环引用
@property(nonatomic, strong) void (^)block;
_block = ^{
NSLog(@"%@", self);
}
block会对引用的外部对象变量强引用
__weak typeof(self) weakSelf = self;
如何block里面有延时操作,一旦销毁就取不到了。
解决:(in the block)
__strong typeof(weakSelf) strongSelf = self;//局部变量,执行完就被销毁了
dispatch_after(^{
NSLog(@"%@", strongSelf);
});