copy 和 strong 的使用总结,@property和@synthesize详解

修饰符copystrong 的使用场景

1、copy修饰符
copy修饰不可变对象

① 如果赋值对象为不可变对象,则与strong修饰符使用上没有区别,不会发生内存拷贝,只是发生了指针的强引用(指针重新指向);
② 如果赋值对象为可变对象,会发生内存的拷贝。例如,可变数组A赋值给copy修饰的NSArray对象B,当A的值发生变化,B不会发生变化。

copy修饰可变对象

copy修饰可变对象时会进行浅拷贝,拷贝出来的内存区域是不可变的。使用不可变对象进行赋值不会有问题,如果使用可变对象赋值,并改变可变对象的值,则会出现崩溃。

小结:

copy修饰符主要用于修饰不可变对象,防止因为可变对象赋值时因为赋值对象的值变化而发生变化。

2、strong修饰符

strong修饰不可变对象时,赋值对象共用同一内存,赋值对象的引用计数+1。赋值对象的值发生变化strong修饰对象的值也会发生变化。
strong修饰可变对象时,如果对象值发生变化不会引起崩溃,因为共用的是同一内存区域。

小结:

strong修饰符主要用于修饰可变对象,防止因为可变对象的值发生变化而引起崩溃。

延伸:self.语法 和 _语法
@property (nonatomic, strong) NSString *string;

实际项目中调用string属性主要有两种方式,self.string或者_string。在说self.string_string之前首先需要了解一下@property 以及 @synthesize两者之间的关系。

@property@synthesize

@synthesize是写在@implementation中,@synthesize 声明的属性 = 变量。意思是,将属性的setter,getter方法,作用于这个变量。

iOS 6 之后 LLVM 编译器引入property autosynthesis,即属性自动合成。换句话说,就是编译器会为每个 @property 添加 @synthesize ,如以下形式:

@synthesize propertyName = _propertyName;

虽然现在我们不必再用@synthesize声明一个实例变量。(注意:是不必要,不是不可以),但是一些特殊情况还是会用到@synthesize
@synthesize可以指定与属性对应的实例变量,例如:

@synthesize age = myAge;

这样的话调用self.age的时候,其实是操作的实例变量myAge,而不是_age了。

② 使用@synthesize为属性添加任意别名,此时使用自动生成的实例变量名将报错,只能使用指定的别名。例如:

@synthesize propertyName = _propertyNameNew;

这样的话,使用_语法调用self.propertyName,只能使用_propertyNameNew,而不能使用_propertyName

③ 还有一种情形需要使用 @synthesize ,就是当在 protocol 中声明并实现属性时。协议中声明的属性不会自动生成settergetter[UIApplicationDelegate window] 就是个典型的例子。
④ 同时重写属性的settergetter方法之后,需要使用 @synthesize 手动生成成员变量。因为同时重写settergetter会导致系统不再自动生成_xx成员变量。

ps:重写setter和getter的注意事项

重写getter时,最后返回return _xx;而不是return self.xx;, 这是因为点语法实际上是对settergetter方法的调用,如果在getter方法中调用return self.xx的话,就会循环调用。

重写setter时,最好在setter方法中添加一行_xx = xx;,以便外部调用_xx

关于 @synthesize 的其他知识点:
① 禁止@synthesize:如果某属性已经在某处实现了自己的 setter/getter ,可以使用 @dynamic 来阻止 @synthesize 自动生成新的 setter/getter 覆盖。
② 自动合成没有任何内存的含义,因为它根本没有连接到ARC。


言归正传,下面继续聊self.语法和_语法的问题。
self.xx实际是对xxsetter/getter方法的调用:
self.xx=的左边调用的是setter方法
self.xx=右边调用的是getter方法
_xx是直接对变量操作,不会调用setter/getter方法

小结:

1、self.xx_xx 的区别主要是在是否调用setter/getter方法。
2、在不需要调用setter/getter方法时使用_xx会提高一些性能,但是需要主要的是,必须在确保xx已经创建之后再用_xx,否则_xxnil

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值