本着虚心学习的原则,在上次看完GCD后,在码代码的过程中,经常会在dispatch后自动跳出函数列中看到带有context,但是在平常的自学过程中,都没有见到过带有context的参数。那他到底指的是啥?
带着这个好奇心,我努力的爬遍了网上我能找到的相关文档。然而相关的资料很少,最后没办法只能去苹果的官方文档上找,最终大概的了解了这个context的作用。(果然,最原始的才是最有效的。)
在官方文档中有这么一个方法void dispatch_async_f( dispatch_queue_t queue, void *context, dispatch_function_t work)
,这个方法和我们日常搜用的dispatch_async
类似,唯一的区别的就是中间增加了context这个参数。
画外音:不是
dispatch_async
中用的是block
,dispatch_async_f
中用的是work么?答:这两个反正都是为了引用一个代码块,实际上的作用基本上都差不多的啦
而苹果对于这个context的解释是这样的:
The application-defined context parameter to pass to the function.
将程序中定义的上下文传递给参数。
那么新的问题又来了,既然他是将上下文传递给参数,我们在OC编码的过程中,主要还是基于Foundation框架,也就是所有对象继承与NSObject对象,但是他是一个OC对象,而这个context所需要的内容是一个基于C语言的指针。那么如果将OC对象转化成C呢?
画外音:我就是不用OC,我用C的malloc也是可以的啊
你出去!
正如我们所知道的,OC是C的拓展,让C拥有了面向对象的作用,从而大大提高的程序员开发的效率。同时苹果为了更方便的让开发者使用OC这门语言,他们在iOS 5以后加入到LLVM 3.0编译器的。同时使用ARC能够解决开发者心烦的手动管理内存问题,这极大的方便了程序猿们。
而C因为没有ARC机制,所以解决前面这个问题的方法就是:
将这个需要传输的对象的内存管理,从ARC手中抢过来。让我们手动来管理,这样就可以愉快的将变量以C的形式传入进去啦~~~
那么既然要解决这个问题,我们就需要寻找,如何将内存管理从ARC中“夺”过来。
在翻遍了许多网页后,这几个函数引入我眼帘:此处参考原文
- __bridge:只做类型转换,不修改需要管理的内存使用权
- __bridge_retained:做类型转换Core Foundation->OC对象,同时将管理权从ARC中移除,后期需要对对象进行手动释放
- __bridge_transfer:做类型转换OC对象->Core Foundation,同时将管理权移回ARC
首先展示显示失败的代码:
|
|
失败原因:由于我们在这里设置为了nil也就是意味着我们将他释放,但是在线程中的data还是调用者,同时因为c中对ARC不进行操作,所以,线程中的data指向的地址出现问题,所以出现EXC_BAD_ACCESS
console中的输出为:
|
|
正确解释的代码:
|
|
正确的输出:
|
|
以上就是Context的基本使用方法,看完之后各位看官们就能愉快的将OC对象作为参数传到已经准备好的dispatch对象的执行函数中了~~~~然而具体如何使用,这个根据具体开发环境决定。