1.Block的值捕获Capture
值捕获- 说明
对于block中使用的auto变量(一般的局部变量),block是值传递,对于static修饰的变量,是指针传递,对于全局变量是直接访问 - 代码
#import "ViewController.h"
@interface ViewController ()
{
int _c;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
int a = 10;
void(^block1)(void) = ^{
NSLog(@"a = %d",a);
};
a = 20;
block1();
static int b = 10;
void(^block2)(void) = ^{
NSLog(@"b = %d",b);
};
b = 20;
block2();
_c = 10;
void(^block3)(void) = ^{
NSLog(@"c = %d",self->_c);
};
_c = 20;
block3();
}
@end
-
运行结果
Capture运行结果
2.Block类型
-
block的三种类型
block类型 -
每一种类型的block调用copy后的结果
block调用copy
3.Block的copy操作
- 在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上.
1. block作为函数返回值时 - 代码
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
typedef void(^YMBlock)(void);
YMBlock getBlock() {
int a = 10;
return ^ {
NSLog(@"a = %d",a);
};
}
int main(int argc, char * argv[]) {
@autoreleasepool {
YMBlock block = getBlock();
NSLog(@"%@",[block class]);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- 运行结果
block作为函数返回值
2. 将block赋值给__strong指针时 - 代码
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
typedef void(^YMBlock)(void);
int main(int argc, char * argv[]) {
@autoreleasepool {
/// 有__strong指针指向
int a = 10;
YMBlock block = ^ {
NSLog(@"%d",a);
};
NSLog(@"%@",[block class]);
// 无__strong指针指向
NSLog(@"%@",[^ {
NSLog(@"%d",a);
} class]);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
-
运行结果
有无__strong指针指向
3. block作为Cocoa API中方法名含有usingBlock的方法参数时
block作为GCD API的方法参数时
NSArray *arr = @[];
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
}];
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
});
网友评论