Block的类型
一、block的三种类型
-
NSGlobalBlock
-
NSStackBlock
-
NSMallocBlock
int age_;
int height_;
void test1() {
int age1 = 10;
void (^block1)(void) = ^{
NSLog(@"%d", age1);
};
age1 = 20;
block1();
NSLog(@"%@",[block1 class]);
}
void test2() {
static int age2 = 10;
void (^block2)(void) = ^{
NSLog(@"%d", age2);
};
age2 = 20;
block2();
NSLog(@"%@",[block2 class]);
}
void test() {
age_ = 10;
height_ = 10;
void (^block)(void) = ^{
NSLog(@"age = %d; height = %d", age_, height_);
};
age_ = 20;
height_ = 20;
block();
NSLog(@"%@", [block class]);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test1(); //__NSMallocBlock__
test2(); //__NSGlobalBlock__
test(); //__NSGlobalBlock__
}
return 0;
}
每种类型的block调用结果如下:
二、block的copy
在arc环境下,编译器会根据情况自动将栈上的block复制到堆上,如以下情况:
-
block作为函数返回值的时候
-
将block赋值给__strong指针的时候
3. block作为CocoaAPI中方法名含有usingblock的方法参数时
4. block作为GCD API的方法参数时
MRC下的block属性的建议写法:
**@property** (**copy**, **nonatomic**) **void** (^blcok)(**void**);
ARC下的block属性的建议写法:
@property (copy, nonatomic) void (^blcok)(void);
@property (strong, nonatomic) void (^blcok)(void);
三、对象类型的auto变量
当block内部访问了对象的auto变量时:
-
如果是在栈上,将不会对auto变量产生强引用
-
如果block被拷贝到堆上
- 会调用block内部的copy函数
- copy函数内部会调用_Block_object_assign函数
- _Block_object_assign函数会根据auto变量的修饰符( __strong、 __weak、 __unsafe_unretained)做出相应操作,形成强引用(retain)或弱引用**
- 如果block从堆上移除
- 会调用block内部的dispose函数
- dispose函数内部会调用_Block_object_dispose函数
**- _Block_object_dispose函数会自动释放auto变量(release)
| 函数 | 调用时机 |
| --- | --- |
| copy | 栈上的block复制到堆时 |
| dispose | 堆上的block被废弃时 |
在使用clang转换OC为C++代码时,可能会遇到以下问题:
cannot create __weak reference in file using manual reference
解决方案:支持ARC、指定运行时系统版本,比如
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m