.点语法和_下划线

2018-11-02  本文已影响11人  gpylove

点语法

        点语法是对属性的访问,经过oc消息派发,可以完成属性所定义的“内存管理语义”, 包含set和get方法。

下划线

        下划线直接访问实例变量,不经消息派发访问速度更快,不会调用set和get方法,不会触发KVO。

注意点

1、懒加载,必须通过下划线来访问变量

2、不要在init和dealloc中使用点语法

        对于 iOS 开发而言,直接使用成员变量效率会优于使用属性,但是直接使用成员变量也有不足之处:对于一个基本类型的变量(double, int)来说确实方便。但对于一个对象来说情况就复杂了,对象是 retain 呢还是 copy 呢?对于直接用成员变量来说,没有给出任何明确地行为,这往往会带来内存方面的问题。另外,如果这样直接的赋值,也不会触发 KVO。 

        使用点语法是更好的选择,因为这样可以兼容懒加载,同时也避免了使用下滑线的时候忽略了self这个指针,后者容易在block中造成循环引用,同时使用下划线是获取不到父类的属性,因为它只是对局部变量的访问。

        所以说我们应该结合起来去使用成员变量和点语法。对于基本数据类型,直接使用成员变量;对于一个 OC 对象,我们在只读操作的时候,直接使用成员变量即可。而在读写操作的时候,用点语法即可。这样一来既避免了内存问题,KVO问题,也尽可能的提高了效率。

小知识:自动合成属性实例变量之后,@synthesize使用场景

1.同时重写了 setter 和 getter 时

2.重写了只读属性的 getter 时

3.使用了 @dynamic 时

4.在 @protocol 中定义的所有属性

5.在 category 中定义的所有属性

6.重载的属性

小知识:懒加载

        懒加载,亦叫延迟加载,即在第一次需要的时候才去加载,本质上就是对一个实例的getter方法的重写。

懒加载的优点

相对来说,如果代码量不是很多,可读性略强;相对来说,防止为nil,减少了后续使用时安全检查的后顾之忧,使用适当,可节省内存资源。

懒加载的缺点

使用太泛滥,导致可读性变差,使用不得当,可能会造成死循环,导致crash,代码量增多。

注意:在懒加载中,用下划线方法,避免死循环。

后记:

@property(copy,nonatomic) NSString *aCopyMStr;

NSMutableString *mstrOrigin = [[NSMutableString alloc] initWithString:@"mstrOriginValue"];

 _aCopyMStr= mstrOrigin;

NSLog(@"mstrOrigin输出:%p,%@\n", mstrOrigin,mstrOrigin);

NSLog(@"aCopyMStr输出:%p,%@\n",_aCopyMStr,_aCopyMStr);

NSLog(@"引用计数%@",[mstrOrigin valueForKey:@"retainCount"]);

2018-11-06 15:21:46.407712+0800 OC-Swift[7127:192355] mstrOrigin输出:0x60000301e850,mstrOriginValue

2018-11-06 15:21:46.407892+0800 OC-Swift[7127:192355] aCopyMStr输出:0x60000301e850,mstrOriginValue

2018-11-06 15:21:46.408095+0800 OC-Swift[7127:192355] 引用计数2

2018-11-06 15:27:50.202765+0800 OC-Swift[7169:194363] mstrOriginValueTest===mstrOriginValueTest

@property(copy,nonatomic) NSString *aCopyMStr;

NSMutableString *mstrOrigin = [[NSMutableString alloc] initWithString:@"mstrOriginValue"];

self.aCopyMStr= mstrOrigin;

NSLog(@"mstrOrigin输出:%p,%@\n", mstrOrigin,mstrOrigin);

NSLog(@"aCopyMStr输出:%p,%@\n",self.aCopyMStr,self.aCopyMStr);

NSLog(@"引用计数%@",[mstrOrigin valueForKey:@"retainCount"]);

[mstrOrigin appendString:@"Test"];    NSLog(@"%@===%@",mstrOrigin,self.aCopyMStr);

2018-11-06 15:22:07.847314+0800 OC-Swift[7127:192355] mstrOrigin输出:0x60000301e850,mstrOriginValue

2018-11-06 15:22:07.847502+0800 OC-Swift[7127:192355] aCopyMStr输出:0x600003019920,mstrOriginValue

2018-11-06 15:22:07.847629+0800 OC-Swift[7127:192355] 引用计数1

2018-11-06 15:33:53.367396+0800 OC-Swift[7258:198057] mstrOriginValueTest===mstrOriginValue

        可见下划线只是访问实例变量,没有完成属性所定义的“内存管理语义”,这会带来内存方面的问题。当属性为copy时,需要用点语法调用属性才会对对象进行深拷贝,而下划线是指针指向相同的内存地址。

上一篇 下一篇

猜你喜欢

热点阅读