iOS中block作为传参

先上结论,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了



你可能感兴趣的:(iOS中block作为传参)