iOS copy、assgin、weak、strong等修饰符

来源:互联网 发布:sql server服务管理器 编辑:程序博客网 时间:2024/05/20 20:21

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

  • NSString、NSArray、NSDictionary等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary

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

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

strong

  • NSObject类型

weak:引用计数器不加1

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

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

readwrite:可读可写(默认)设置可访问级别

retain:释放(release)旧对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

  • NSObject类型
  • copy可以是深拷贝,而retain使用时浅拷贝:比如一个NSString对象,地址为0x1111,内容为@”LOLITA” ,copy到另外一个NSString之后,地址为0x2222,内容相同,新的对象retain为1,旧有对象加1。

nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。


扩展

为什么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修饰NSString、NSDictionary、NSArray的区别

分别使用两种修饰符来修饰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


参考地址

iOS进阶(一)block与property