1. 什么情况下用weak关键字,相比assign有什么区别?
- 使用weak关键字的情况:
- 在ARC中,有可能造成循环引用的时候,往往会在其中一端使用weak修饰,比如:delegate代理属性
- 自身已经对他进行了一次强引用,没有必要再次强引用,此时也会使用weak,如:自定义IBOutlet控件属性,当然也可以使用strong
- 不同点:
- weak只能在ARC环境下修饰OC对象,assign可以修饰非OC对象
- weak属性表示的是一种非拥有关系,这种属性设置新值时,设置方法既不会保留新值,也不会释放旧值。在属性所指的对象被摧毁时,属性值也会被清空。assgin设置新值时只是对纯量类型进行简单的赋值操作。
2. @property的本质是什么?ivar、getter、setter是如何生成并添加到这个类中的
- @property的本质
@property = ivar(实例变量) + getter(获取方法) + setter(设置方法)
- ivar、getter、setter是如何生成并添加到这个类中的
通过自动合成的
属性定义完成后,编译器会自动编写这些属性的存取方法。这个过程是在编译器编译器执行的,所以编辑器里看不到这些“合成方法”的源代码。出了生成方法代码getter、setter之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性签名加下划线,以此作为实例变量的名字。
3. @protocol和category中如何使用@property
- protocol中使用property只会生成setter和getter方法的声明,我们使用属性的目的,是希望遵循我协议的对象能实现该属性。
- category中使用property只会生成setter和getter方法的声明,如果需要给category增加属性的实现,需要借助runtime运行时的两个函数:
objc_setAssociatedObject
和objc_getAssociatedObject
4. @synthesize和@dynamic的作用
- 如果property对应的@synthesize和 @dynamic都没写,那么默认的就是@synthesize var = _var
- @synthesize 的语义是如果你没有手动实现setter和getter方法,那么编译器会自动为你加上这两个方法。
- @dynamic告诉编译器属性的setter和getter方法由用户自己实现,不自动生成。(对于readonly的属性只需提供getter方法)。假如一个声明为@dynamic var,然后你没有提供setter方法和getter方法,编译的时候没问题,但是当程序运行到instance.var = someVar,由于缺乏setter方法会导致程序崩溃,或者当运行到 someVar = instance.var时,由于缺乏方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的“动态绑定”。
5. __weak、__block理解
-
__weak
__weak
只能在ARC模式下使用,只能修饰对象类型,不能修饰基本数据类型(如int等),__weak
修饰的对象在block中不可以被重新赋值。使用__weak
修饰,可以避免循环引用。
__weak __typeof(self) weakSelf = self;
self.block = ^{
[weakSelf doSomeThing];
});
2.__block
__block
不管是ARC还是MRC模式下都可以使用,可以修饰对象类型,也可以修饰基本数据类型。在MRC下使用__block是可以避免循环引用的。在ARC下使用__block typeof(self) weakSelf = self
时,block是用作添加引用来访问实例变量的,所以self会被retain一次,block也是一个强引用,所以会一起循环引用。__block修饰对象会增加引用。
持续更新
网友评论