iOS中block作为传参

2019-01-04  本文已影响0人  小楼又春风

先上结论,block作为参数使用时

1、mrc下使用block要手动拷贝到堆上

2、arc下不用,会自动拷贝到堆上

举一个写异步线程处理的代码时出现一个crash的例子,截图如下

可以看到,task是个block,现在已经为null了,调用发生了crash

可以看下整个调用的过程:

1、调用一个接口,传入block

2、接口实现里将block放到了异步线程去处理,然后返回

3、接着就是如上面那个doBlock的那个图了,执行时task变为了null

究其原因,是因为我使用的是mrc来编译,传入block(即task)到asyncWork时,这个task在栈上,如下图,是__NSStackBlock__类型的block

然后调用performSelector将其传入异步线程去处理,由于是异步线程,这时候会立即返回,再返回到最初调用asyncWork的地方执行结束后,栈被收回了,所以task成了null了,自然发生了crash。

解决方案:

1、 如果一定是mrc,使用copy将block拷贝到堆上,这样有着引用,自然不会被回收,结果如下

threadTask tmptask = [[task copy] autorelease];

2、改为arc,这样调用时候会自动拷贝到堆上

调用处还是栈block

传入方法里便是堆block了

上一篇下一篇

猜你喜欢

热点阅读