1 #import "ViewController.h" 2 3 @interface ViewController () 4 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad { 10 11 [super viewDidLoad]; 12 13 [self showResultByNumber1:10086 14 andNumber2:10000 15 andBlock:^(int num1,int num2){ 16 return num1 +num2; 17 }]; 18 19 // [self textBlockTeDian]; 20 // [self textBlockTeDian1]; 21 // [self textBlockTeDian2]; 22 [self textBlockTeDian3]; 23 } 24 25 #pragma mark - block基本语法 26 - (void)block1 27 { 28 /* 29 block(闭合代码块)- (返回值类型)(^block名)(参数列表) 30 31 block类型:(返回值类型)(^)(参数列表) 32 block的名:block名 33 34 block不遵守引用计数 35 block的执行效率非常高 36 block一般被用界面传值,或者当做方法参数实现方法回调 37 */ 38 } 39 40 #pragma mark - block基本用法 41 - (void)block2 42 { 43 44 //赋值语句 45 //block的实体在赋值的过程中不会被执行, 46 //当且仅当block被调用的时候,block的实体才会被执行 47 48 //block并不是方法,所以执行的时候并不需要self调用。直接执行即可 49 50 void (^block)(void) = ^{ 51 52 NSLog(@"Hello Word"); 53 }; 54 block(); 55 56 //int (^blockSum)(int, int) 表示, 57 //定义一个[有两个整形参数,返回值为整形]的blockSum的代码块 58 int (^blockSum)(int, int) = ^(int num1,int num2){ 59 return num1 + num2; 60 61 }; 62 NSLog(@"%d",blockSum(56,78)); 63 64 } 65 66 #pragma mark - block用作方法参数 67 - (void)showResultByNumber1:(int)number1 68 andNumber2:(int)number2 69 andBlock:(int(^)(int,int))block 70 { 71 NSLog(@"Result:%d",block(number1,number2)); 72 } 73 74 #pragma mark - block特点 75 //值锁定(值拷贝)是针对于存储在堆栈区的数据 76 77 //值锁定-针对常变量 78 - (void)textBlockTeDian 79 { 80 int number = 8; 81 /* 82 如果block内部引用了block外部的任意变量 83 那么这个block在ARC环境下 84 自动从static(栈)区copy到malloc(堆)区 85 86 block实体存在代码区,实体在编译的过程中已经执行了,编译时已经值锁定 87 */ 88 int (^block)(int) = ^(int num){ 89 return num +number; 90 }; 91 92 number = 4; 93 NSLog(@"number:%d",block(9)); 94 } 95 //值锁定-指针类型 96 - (void)textBlockTeDian1 97 { 98 NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"1",@"3", nil]; 99 NSMutableArray *(^block)(NSMutableArray *) = ^(NSMutableArray *tempArr) 100 { 101 //值锁定,锁定的是数组arr的首地址 102 [arr addObject:tempArr]; 103 return arr; 104 }; 105 106 [arr removeObject:@"1"]; 107 NSMutableArray *objArr = [[NSMutableArray alloc] initWithObjects:@"2", nil]; 108 NSLog(@"%@",block(objArr)); 109 110 } 111 //静态变量 112 - (void)textBlockTeDian2 113 { 114 // 静态修饰符,存在代码全局仅执行一次 115 static int number = 8; 116 117 int (^block)(int) = ^(int num){ 118 // 因为静态变量的存储位置并不在堆栈区,因此值锁定的时候不会对静态变量的值进行任何保存 119 return num +number; 120 }; 121 122 number = 4; 123 NSLog(@"number:%d",block(9)); 124 125 } 126 // __block 127 - (void)textBlockTeDian3 128 { 129 //__block 修饰的变量,可以在多个block中共同使用 130 //相当于在block内部声明的变量 131 __block int i = 10; 132 133 int (^block1)(int) = ^(int number){ 134 135 i = i +number; 136 return i; 137 }; 138 139 int (^block2)(int) = ^(int num){ 140 141 i = i + num; 142 return i; 143 }; 144 NSLog(@"block1--->i=%d",block1(4)); 145 NSLog(@"block2--->i=%d",block2(9)); 146 147 } 148 149 @end
1 /* 2 11.block的三种分类 3 (堆区block)、(栈区block)、(Globle区block) 4 12.block的循环引用(以及如何避免) 5 13.关于block的内存管理 6 7 */ 8 #import "ViewController.h" 9 typedef NSString* (^myBlock)(NSString*); 10 11 @interface ViewController () 12 13 @property (copy, nonatomic) NSString *myStr; 14 @property (copy, nonatomic) myBlock block; 15 16 @end 17 18 @implementation ViewController 19 20 - (void)viewDidLoad { 21 [super viewDidLoad]; 22 23 //循环引用导致的[block不释放,界面不释放] 24 // [self blockCircleUsed]; 25 // [self showBlockType]; 26 // [self showGlobleBlockRetainCount]; 27 [self showStackBlockRetainCount]; 28 // [self showMallocBlockRetainCount]; 29 } 30 #pragma mark - 循环引用 31 - (void)blockCircleUsed 32 { 33 //在这里VC引用了block 34 //VC->block 35 36 __weak ViewController *vc = self; 37 self.block = ^(NSString *str){ 38 39 //block内部引用了当前VC的属性 40 //此时block->VC 41 //如何解决:将block内部的VC变成一个指向VC的弱引用 42 NSLog(@"%@",vc.myStr); 43 return vc.myStr; 44 }; 45 46 } 47 48 49 #pragma mark - GlobleBlock 内存管理测试 50 - (void)showGlobleBlockRetainCount 51 { 52 void (^globleBlock)(void) = ^{ 53 NSLog(@"here is globleBlock"); 54 }; 55 NSLog(@"1=====>%ld",[globleBlock retainCount]); 56 [globleBlock retain]; 57 NSLog(@"2=====>%ld",[globleBlock retainCount]); 58 [globleBlock release]; 59 NSLog(@"3=====>%ld",[globleBlock retainCount]); 60 globleBlock(); 61 } 62 #pragma mark - StackBlock内存管理测试 63 - (void)showStackBlockRetainCount 64 { 65 NSArray *arr = @[@"1",@"2"]; 66 67 void (^stackBlock)(void) = ^{ 68 NSLog(@"%@",arr); 69 }; 70 NSLog(@"1=====>%ld",[stackBlock retainCount]); 71 [stackBlock retain]; 72 NSLog(@"2=====>%ld",[stackBlock retainCount]); 73 [stackBlock release]; 74 NSLog(@"3=====>%ld",[stackBlock retainCount]); 75 stackBlock(); 76 } 77 78 #pragma mark - MallocBlock 内存管理测试 79 - (void)showMallocBlockRetainCount 80 { 81 //block不遵循引用计数原则,所以不能使用ARC自动管理内存管理block 82 // NSArray *arr = @[@"1",@"2"]; 83 // void (^block)(void) = ^{ 84 // NSLog(@"%@",arr); 85 // }; 86 //既然通常情况下不需要我们手动管理block的内存,那就意味着一件事,我们的程序当中不能出现过多的block 87 88 89 // NSLog(@"------>%ld",[[block copy] retainCount]); 90 // [block retain]; 91 // NSLog(@"======>%ld",[[block copy] retainCount]); 92 // [block release]; 93 // NSLog(@"======>%ld",[[block copy] retainCount]); 94 // block(); 95 } 96 97 #pragma mark - block三种类型 98 - (void)showBlockType 99 { 100 //MRC环境下才能看到,ARC下看不到 101 //--------------------------// 102 NSArray *arr = @[@"1",@"2"]; 103 104 // globle类型block 105 NSLog(@"%@",^{ 106 NSLog(@"hello world"); 107 }); 108 109 // NSStackBlock(栈区block) 110 NSLog(@"%@",^{ 111 NSLog(@"%@",arr); 112 }); 113 114 // NSMallocBlock(堆区block) 115 void(^block)(void) = ^{ 116 NSLog(@"%@",arr); 117 }; 118 NSLog(@"%@",[block copy]); 119 } 120 121 @end