Hai Nan

但行好事,莫问前程.

记录知识点


Block

UIView 的动画代码, 我们在使用 UIView 的 animateWithDuration:animations 方法 做动画的时候, 并不需要使用 weak self, 因为引用持有关系是:

  • UIView 的某个负责动画的对象持有了 block
  • block 持有了 self

因为 self 并不持有 block, 所以就没有循环引用产生, 因为就不需要使用 weak self 了


在 block 中先写一个 strongSelf 其实是为了避免 block 的执行过程中, 突然出现 self 被释放的尴尬情况. 通常情况下, 如果不这么做的话, 还是很容易出现一些奇怪的逻辑, 甚至闪退.


__forwarding指针这里的作用就是针对堆的Block,把原来__forwarding指针指向自己,换成指向_NSConcreteMallocBlock上复制之后的__block自己。然后堆上的变量的__forwarding再指向自己。这样不管__block怎么复制到堆上,还是在栈上,都可以通过(i->__forwarding->i)来访问到变量值。


在ARC环境下,Block也是存在__NSStackBlock的时候的


5种变量,自动变量,函数参数 ,静态变量,静态全局变量,全局变量,如果严格的来说,捕获是必须在Block结构体__main_block_impl_0里面有成员变量的话,Block能捕获的变量就只有带有自动变量和静态变量了。捕获进Block的对象会被Block持有。

对于非对象的变量来说,

自动变量的值,被copy进了Block,不带__block的自动变量只能在里面被访问,并不能改变值。

带__block的自动变量 和 静态变量 就是直接地址访问。所以在Block里面可以直接改变变量的值。

而剩下的静态全局变量,全局变量,函数参数,也是可以在直接在Block中改变变量值的,但是他们并没有变成Block结构体__main_block_impl_0的成员变量,因为他们的作用域大,所以可以直接更改他们的值。

值得注意的是,静态全局变量,全局变量,函数参数他们并不会被Block持有,也就是说不会增加retainCount值。

对于对象来说,

在MRC环境下,__block根本不会对指针所指向的对象执行copy操作,而只是把指针进行的复制。 而在ARC环境下,对于声明为__block的外部对象,在block内部会进行retain,以至于在block环境内能安全的引用外部对象。对于没有声明__block的外部对象,在block中也会被retain。


参考

[转]面试题: block中关于self的一些问题

深入研究 Block 捕获外部变量和 __block 实现原理

最近的文章

include import class

import的功能与#include差不多,但是可以解决头文件重复导入的问题,而#include会有重复导入头文件的问题class A.h使用了#import “B.h”class B.h使用了#import “A.h”那么这就会导致了头文件循环引用的问题了,通常都是出现虽然你导入了该头文件,但在使用时比如使用@propery(nonatomic)A *a;会出现: Unknown Type 之类错误. 所以这个时候@class就派上用场了。参考#include、#import与@clas...…

继续阅读
更早的文章

代理

强代理在iOS中存在一类strong类型的delegate, 比如CoreAnimation的代理和NSURLSession的代理. 使用强代理是因为动画和网络请求在异步执行, 而异步执行中随时可能会丢失销毁对象, 当执行完成之后再手动销毁对象. 因此要使用strong delegate, 必须当任务完完成时在将delegate=nil来释放delegate.参考iOS中的强代理(strong delegate)…

继续阅读