iOS 基础 - 属性修饰符

copy

建立一个索引数为一的对象,然后释放旧对象。

  • NSString、NSArray、NSDictionary 等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,为了保证在使用过程中不会被修改,使用 copy 复制出新的对象。

assgin

简单赋值,不更改索引计数。

  • 适用于基本数据类型:NSInteger、BOOL、CGFloat等

strong

ARC 下默认模式,释放旧对象,引用新对象,并使新对象的计数器加一。使用绝大部分 NSObject 对象。

weak

引用新对象,该对象的计数器不加一。

  • 在ARC模式下,解决循环引用导致内存泄漏的问题,使用weak关键字
  • 自身已经对它进行了一次强引用,没有必要再强引用的时候,使用weak关键字

readonly

表示这个属性是只读的,只生成getter方法,不会生成setter方法。

readwrite

可读可写(默认)设置可访问级别,ARC 下默认修饰符。

retain

MRC 下的 strong ,释放(release)旧对象,引用新对象,并使新对象的计数器加一。

nonatomic

非原子性访问,不加同步,多线程并发访问会提高性能。

atomic

原子性访问,最属性的 settergetter 进行加锁操作以保证值的完整性。

扩展

为什么NSString、NSDictionary、NSArray要使用copy修饰符呢?

要搞清楚这个问题,我们先来弄明白深拷贝与浅拷贝的区别,以非集合类与集合类两种情况来进行说明下,先看非集合类的情况,代码如下:

NSString *name = @"LOLITA";
NSString *newName = name.copy;
NSLog(@"name address:%p ---- newName address:%p",name,newName);

输出信息如下:

name address:0x1000d0520 ---- newName address:0x1000d0520

可以看出复制过后,内存地址是一样的,没有发生变化,这就是浅拷贝,只是把指针的地址复制了一份;

我们修改代码为name.mutableCopy,此时输出的信息图下:

name address:0x1000f4520 ---- newName address:0x17426fb40

此时内存地址发生了变化,并且newName的内存地址的偏移量比name的内存地址大许多,由此可见name经过mutableCopy操作之后,被复制到新的区域了,这就是深拷贝,深拷贝不仅拷贝地址还拷贝了内容。

上面的都是不可变对象,在看下可变对象的情况,代码如下:

NSMutableString *name = [[NSMutableString alloc] initWithString:@"LOLITA"];
NSMutableString *newName = name.copy;
NSLog(@"name address:%p ---- newName address:%p",name,newName);

输出信息如下:

name address:0x17026cdc0 ---- newName address:0xa004154494c4f4c6

从上面可以看出copy之后,内存地址不一样,这是深复制,内容也就进行拷贝。在把代码改成name.mutableCopy,此时日志的输出信息如下:

name address:0x17007a380 ---- newName address:0x17007d6c0

可以看出可变对象copy与mutableCopy的效果是一样的,都是深拷贝。

总结:对于非集合类对象的copy操作如下:

  • [immutableObject copy]; // 浅拷贝

  • [immutableObject mutableCopy]; // 深拷贝

  • [mutableObject copy]; // 深拷贝

  • [mutableObject mutableCopy]; // 深拷贝

采用同样的方法可以验证集合类对象的copy操作如下:

  • [immutableObject copy]; // 浅拷贝

  • [immutableObject mutableCopy]; // 单层深拷贝

  • [mutableObject copy]; // 深拷贝

  • [mutableObject mutableCopy]; // 深拷贝

对于NSString、NSDictionary、NSArray等经常使用copy关键字,是因为它们有对应的可变类型:NSMutableString、NSMutableDictionary、NSMutableArray,它们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性时拷贝一份。

strong 和 copy 修饰区别**

分别使用两种修饰符来修饰NSArray

@property (copy ,nonatomic) NSArray *bookArray1;
@property (strong ,nonatomic) NSArray *bookArray2;

NSMutableArray *books = [NSMutableArray arrayWithObject:@"book1"];
self.bookArray1 = books;
self.bookArray2 = books;
[books addObject:@"book2"];	// 当数组改变时
NSLog(@"bookArray1:%@",self.bookArray1);
NSLog(@"bookArray2:%@",self.bookArray2);

输出结果:

bookArray1:(
   book1
)
bookArray2:(
    book1,
    book2
)

由此可以看出,books 被改变时,strong 修饰的 bookArray2 也随之改变。

这说明strong对books进行浅拷贝,只拷贝了指针,books 和 bookArray2 指向同一个地址,内容是一样的。

而copy对books进行了深拷贝,是针对内容进行了拷贝,所以books的改变不会影响到bookArray1。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值