#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self showResultByNumber1:
andNumber2:
andBlock:^(int num1,int num2){
return num1 +num2;
}]; // [self textBlockTeDian];
// [self textBlockTeDian1];
// [self textBlockTeDian2];
[self textBlockTeDian3];
} #pragma mark - block基本语法
- (void)block1
{
/*
block(闭合代码块)- (返回值类型)(^block名)(参数列表) block类型:(返回值类型)(^)(参数列表)
block的名:block名 block不遵守引用计数
block的执行效率非常高
block一般被用界面传值,或者当做方法参数实现方法回调
*/
} #pragma mark - block基本用法
- (void)block2
{ //赋值语句
//block的实体在赋值的过程中不会被执行,
//当且仅当block被调用的时候,block的实体才会被执行 //block并不是方法,所以执行的时候并不需要self调用。直接执行即可 void (^block)(void) = ^{ NSLog(@"Hello Word");
};
block(); //int (^blockSum)(int, int) 表示,
//定义一个[有两个整形参数,返回值为整形]的blockSum的代码块
int (^blockSum)(int, int) = ^(int num1,int num2){
return num1 + num2; };
NSLog(@"%d",blockSum(,)); } #pragma mark - block用作方法参数
- (void)showResultByNumber1:(int)number1
andNumber2:(int)number2
andBlock:(int(^)(int,int))block
{
NSLog(@"Result:%d",block(number1,number2));
} #pragma mark - block特点
//值锁定(值拷贝)是针对于存储在堆栈区的数据 //值锁定-针对常变量
- (void)textBlockTeDian
{
int number = ;
/*
如果block内部引用了block外部的任意变量
那么这个block在ARC环境下
自动从static(栈)区copy到malloc(堆)区 block实体存在代码区,实体在编译的过程中已经执行了,编译时已经值锁定
*/
int (^block)(int) = ^(int num){
return num +number;
}; number = ;
NSLog(@"number:%d",block());
}
//值锁定-指针类型
- (void)textBlockTeDian1
{
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"",@"", nil];
NSMutableArray *(^block)(NSMutableArray *) = ^(NSMutableArray *tempArr)
{
//值锁定,锁定的是数组arr的首地址
[arr addObject:tempArr];
return arr;
}; [arr removeObject:@""];
NSMutableArray *objArr = [[NSMutableArray alloc] initWithObjects:@"", nil];
NSLog(@"%@",block(objArr)); }
//静态变量
- (void)textBlockTeDian2
{
// 静态修饰符,存在代码全局仅执行一次
static int number = ; int (^block)(int) = ^(int num){
// 因为静态变量的存储位置并不在堆栈区,因此值锁定的时候不会对静态变量的值进行任何保存
return num +number;
}; number = ;
NSLog(@"number:%d",block()); }
// __block
- (void)textBlockTeDian3
{
//__block 修饰的变量,可以在多个block*同使用
//相当于在block内部声明的变量
__block int i = ; int (^block1)(int) = ^(int number){ i = i +number;
return i;
}; int (^block2)(int) = ^(int num){ i = i + num;
return i;
};
NSLog(@"block1--->i=%d",block1());
NSLog(@"block2--->i=%d",block2()); } @end
/*
11.block的三种分类
(堆区block)、(栈区block)、(Globle区block)
12.block的循环引用(以及如何避免)
13.关于block的内存管理 */
#import "ViewController.h"
typedef NSString* (^myBlock)(NSString*); @interface ViewController () @property (copy, nonatomic) NSString *myStr;
@property (copy, nonatomic) myBlock block; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //循环引用导致的[block不释放,界面不释放]
// [self blockCircleUsed];
// [self showBlockType];
// [self showGlobleBlockRetainCount];
[self showStackBlockRetainCount];
// [self showMallocBlockRetainCount];
}
#pragma mark - 循环引用
- (void)blockCircleUsed
{
//在这里VC引用了block
//VC->block __weak ViewController *vc = self;
self.block = ^(NSString *str){ //block内部引用了当前VC的属性
//此时block->VC
//如何解决:将block内部的VC变成一个指向VC的弱引用
NSLog(@"%@",vc.myStr);
return vc.myStr;
}; } #pragma mark - GlobleBlock 内存管理测试
- (void)showGlobleBlockRetainCount
{
void (^globleBlock)(void) = ^{
NSLog(@"here is globleBlock");
};
NSLog(@"1=====>%ld",[globleBlock retainCount]);
[globleBlock retain];
NSLog(@"2=====>%ld",[globleBlock retainCount]);
[globleBlock release];
NSLog(@"3=====>%ld",[globleBlock retainCount]);
globleBlock();
}
#pragma mark - StackBlock内存管理测试
- (void)showStackBlockRetainCount
{
NSArray *arr = @[@"",@""]; void (^stackBlock)(void) = ^{
NSLog(@"%@",arr);
};
NSLog(@"1=====>%ld",[stackBlock retainCount]);
[stackBlock retain];
NSLog(@"2=====>%ld",[stackBlock retainCount]);
[stackBlock release];
NSLog(@"3=====>%ld",[stackBlock retainCount]);
stackBlock();
} #pragma mark - MallocBlock 内存管理测试
- (void)showMallocBlockRetainCount
{
//block不遵循引用计数原则,所以不能使用ARC自动管理内存管理block
// NSArray *arr = @[@"1",@"2"];
// void (^block)(void) = ^{
// NSLog(@"%@",arr);
// };
//既然通常情况下不需要我们手动管理block的内存,那就意味着一件事,我们的程序当中不能出现过多的block // NSLog(@"------>%ld",[[block copy] retainCount]);
// [block retain];
// NSLog(@"======>%ld",[[block copy] retainCount]);
// [block release];
// NSLog(@"======>%ld",[[block copy] retainCount]);
// block();
} #pragma mark - block三种类型
- (void)showBlockType
{
//MRC环境下才能看到,ARC下看不到
//--------------------------//
NSArray *arr = @[@"",@""]; // globle类型block
NSLog(@"%@",^{
NSLog(@"hello world");
}); // NSStackBlock(栈区block)
NSLog(@"%@",^{
NSLog(@"%@",arr);
}); // NSMallocBlock(堆区block)
void(^block)(void) = ^{
NSLog(@"%@",arr);
};
NSLog(@"%@",[block copy]);
} @end