转载

iOS中Block使用探索

Block介绍

Block在ios 4.0之后加入,并大量使用在新的ios api中。block是一个匿名的代码块,可以作为传递给其他对象的参数,并得到返回值。从本质上讲,block同其他普通的变量类似,只是其储存的数据是一个函数体。Block不只是针对Objective-C的专利,而是一种可以应用于C、C++和OBjective-C的语言层面的新特性。通过使用block,开发者可以将一段代码段像某一个数值一样当做参数传递给函数。同时,blocks也是Objective-C的一种对象,可以像其他对象一样添加到NSArray或者NSDictionary等集合中。

  • 块语法,本质上是匿名函数。与函数指针很相似
  • Block 封装了一段代码 , 可以在任何时候执行
  • Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。

Block基本使用

1> 如何定义block变量

 int (^sumBlock)(int, int);   void (^myBlock)();   int (^myBlock)(int) = ^(int num){ return num *multiplier }; 

iOS中Block使用探索

2> 如何利用block封装代码

  ^(int a, int b) {      return a - b;   };      ^() {      NSLog(@"----------");   };      ^ {      NSLog(@"----------");   }; 

3> block访问外面变量

* block内部可以访问外面的变量

* 默认情况下,block内部不能修改外面的局部变量

* 给局部变量加上__block关键字,这个局部变量就可以在block内部修改

* 给局部变量加上static关键字,这个局部变量就可以在block内部修改  

4> 利用typedef定义block类型

  typedef int (^MyBlock)(int, int);   // 以后就可以利用MyBlock这种类型来定义block变量   MyBlock block;   MyBlock b1, b2;      b1 = ^(int a, int b) {      return a - b;   };      MyBlock b3 = ^(int a, int b) {      return a - b;   }; 

Block使用的细节和本质

1.block实际上是指向结构体的指针

2.编译器会将block的内部代码生成对应的函数

Block的内存管理

1.默认情况下, block的内存是在栈中

* 它不会对所引用的对象进行任何操作

2.如果对block做一次copy操作, block的内存就会在堆中

* 它会对所引用的对象做一次retain操作

* 非ARC : 如果所引用的对象用了__block修饰, 就不会做retain操作

* ARC : 如果所引用的对象用了__unsafe_unretained/__weak修饰, 就不会做retain操作

这里有一篇个人比较喜欢的关于Block内存管理文章,有兴趣研究的可以看看: Block 的内存管理

Block使用注意

1、在使用block前需要对block指针做判空处理。

不判空直接使用,一旦指针为空直接产生崩溃。

 if (!self.isOnlyNet) {      if (succBlock == NULL) { //后面使用block之前要先做判空处理          return;      }      id data = [NSKeyedUnarchiver unarchiveObjectWithFile:[self favoriteFile]];      if ([data isKindOfClass:[NSMutableArray class]]) {          succBlock(data,YES);      }else{          succBlock(nil,YES);      }  } 

2、使用方将self或成员变量加入block之前要先将self变为__weak

3、在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。

 __weak __typeof(self)weakSelf = self;  AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {      __strong __typeof(weakSelf)strongSelf = weakSelf;      strongSelf.networkReachabilityStatus = status;      if (strongSelf.networkReachabilityStatusBlock) {          strongSelf.networkReachabilityStatusBlock(status);      }  }; 

Block使用场景

(待完成)

Block的妙用

(待完成)

利用Block实现链式编程 

(待完成)

Block总结

(待完成)

正文到此结束
Loading...