【iOS】属性关键字

打印 上一主题 下一主题

主题 1002|帖子 1002|积分 3006

目录

深浅拷贝
自界说类
容器类深拷贝
属性关键字
原子操作
atomic
nonatomic
读写权限
readwrite
readonly
内存管理
weak
assign
strong
retian
copy
strong与copy
补充
属性关键字格式
ARC下@property的默认属性


深浅拷贝

关于深浅拷贝,笔者在之前已经有博客进行过详细的阐述,下面附上深浅拷贝的链接
深浅拷贝
在这篇博客中,笔者讲述了深浅拷贝的基本概念和区别,也解释了一些有关于容器类深拷贝的知识,这里来做一些补充。
自界说类

自界说类无论是copy还是mutablecopy都为深拷贝,因为自界说类没有copyWithZone:和mutableCopyWithZone:两个方法,必要遵守NSCopying和NSMutableCopying协议本身实现这两个拷贝方法。
容器类深拷贝

容器类对象的深拷贝分为两种,一种是单层深拷贝,另一种是完全深拷贝。
   

  • 单层深拷贝:对于副本对象本身是深拷贝,但是容器中的全部对象都是浅拷贝
  • 完全深拷贝:对于副本对象本身与其里面的全部对象都是深拷贝
  非可变容器类在mutablecopy时是单层深拷贝,可变容器类在利用copy和mutablecopy时都是单层深拷贝,那么要如何才气实现容器类的完全深拷贝呢?
先给出结论:当容器类对象中的对象是自界说对象或不为immutable对象,利用initWithArray:copyItems:方法(第二个参数设置为YES)可以实现完全深拷贝;当容器内对象是容器类时,利用initWithArray:copyItems:方法(第二个参数设置为YES)可以实现单层浅拷贝,这时就必要利用归档息争档来实现完全深拷贝
比如:dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]]
  1. - (void)test {
  2.     NSMutableArray* array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],
  3.                               [NSMutableString stringWithString:@"2"],
  4.                               [NSMutableString stringWithString:@"3"],
  5.                               [NSMutableString stringWithString:@"4"],
  6.                               nil];
  7.     NSMutableArray* array2 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"one"],
  8.                               [NSMutableString stringWithString:@"two"],
  9.                               [NSMutableString stringWithString:@"three"],
  10.                               [NSMutableString stringWithString:@"four"],
  11.                               array1,
  12.                               nil];
  13.     NSMutableArray* array3 = [array2 mutableCopy];
  14.     //NSMutableArray* array4 = [[NSMutableArray alloc] initWithArray:array2 copyItems:YES];
  15.     NSMutableString* mutableString;
  16.     mutableString = array2[0];
  17.     [mutableString appendString:@"--ONE"];
  18.     NSLog(@"array3:%@", array3);
  19.     NSLog(@"array2:%@", array2);
  20. }
复制代码

这段代码容器类对象利用mutablecopy,输出的结果是修改array2中的元素,array3也会发生改变,分析这是单层深拷贝,也就是说对于array2和array3是深拷贝,而对于数组中的元素却还是浅拷贝。
如果利用initWithArray:copyItems:方法呢?
  1. - (void)test {
  2.     NSMutableArray* array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],
  3.                               [NSMutableString stringWithString:@"2"],
  4.                               [NSMutableString stringWithString:@"3"],
  5.                               [NSMutableString stringWithString:@"4"],
  6.                               nil];
  7.     NSMutableArray* array2 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"one"],
  8.                               [NSMutableString stringWithString:@"two"],
  9.                               [NSMutableString stringWithString:@"three"],
  10.                               [NSMutableString stringWithString:@"four"],
  11.                               array1,
  12.                               nil];
  13.     NSMutableArray* array3 = [array2 mutableCopy];
  14.     NSMutableArray* array4 = [[NSMutableArray alloc] initWithArray:array2 copyItems:YES];
  15.     NSMutableString* mutableString;
  16.     mutableString = array2[0];
  17.     [mutableString appendString:@"--ONE"];
  18.     NSLog(@"array3:%@", array3);
  19.     NSLog(@"array2:%@", array2);
  20.     NSLog(@"array4:%@", array4);
  21. }
复制代码

可以看出,array4实现了完全深拷贝。
那如果是针对于容器类里的容器类对象呢?
  1. - (void)test {
  2.     NSMutableArray* array1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],
  3.                               [NSMutableString stringWithString:@"2"],
  4.                               [NSMutableString stringWithString:@"3"],
  5.                               [NSMutableString stringWithString:@"4"],
  6.                               nil];
  7.     NSMutableArray* array2 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"one"],
  8.                               [NSMutableString stringWithString:@"two"],
  9.                               [NSMutableString stringWithString:@"three"],
  10.                               [NSMutableString stringWithString:@"four"],
  11.                               array1,
  12.                               nil];
  13.     NSMutableArray* array3 = [array2 mutableCopy];
  14.     NSMutableArray* array4 = [[NSMutableArray alloc] initWithArray:array2 copyItems:YES];
  15.     NSMutableString* mutableString;
  16.     mutableString = array2[0];
  17.     [mutableString appendString:@"--ONE"];
  18.     NSMutableString* mutableString1;
  19.     NSMutableArray* mutableArray = array2[4];
  20.     mutableString1 = mutableArray[0];
  21.     [mutableString1 appendString:@"--ONE"];
  22.     NSLog(@"array3:%@", array3);
  23.     NSLog(@"array2:%@", array2);
  24.     NSLog(@"array4:%@", array4);
  25. }
复制代码
 

 可以看出容器类中的容器类对象利用initWithArray:copyItems:只能实现单层的深拷贝。
属性关键字

@property
@synthesize
@dynamic
这三个关键字是有关于属性自动合成存取方法的关键字:
用 @property 语法来声明属性。@property 会帮我们自动天生属性的 setter 和 getter 方法的声明
@synthesize帮我们自动天生 setter 和 getter 方法的实现以及合成实例变量。
@dynamic告诉编译器不消自动进行 @synthesize,你会在运行时再提供这些方法的实现,无需产生告诫
现在的版本已经不再必要@synthesize 编译器会自动合成存取方法。
下面是一些修饰属性的关键字
原子操作

   原子操作:属性是否有原子性可以理解为线程是否安全
  

  • atomic
原子性,加同步锁,默认修饰符。 利用atomic会损耗性能,也不一定包管线程安全。如果包管线程安全必要利用其他锁机制。


  • nonatomic
非原子性,不实用同步锁。 声明属性时基本设置为nonatomic。利用nonatomic可以或许进步访问性能。
读写权限

读写权限不写时默以为 readwrite


  • readwrite
属性拥有setter方法和getter方法


  • readonly
仅有getter方法
内存管理

weak


  • ARC 下才气利用;
  • 修饰弱引用,不增加对象引用计数,重要可以用于避免循环引用;
  • weak 修饰的对象在被释放之后,会自动将指针置为 nil,不会产生悬垂指针;
assign


  • 既可以修饰基本数据范例,也可以修饰对象范例;
  • setter 方法的实现是直接赋值,一样平常用于基本数据范例 
  • 修饰对象范例时,不增加其引用计数;
  • 会产生悬垂指针(悬垂指针:assign 修饰的对象在被释放之后,指针仍然指向原对象地点,该指针变为悬垂指针。这时候如果继续通过该指针访问原对象的话,就可能导致程序瓦解)。
strong


  • ARC 下才气利用;
  • 原理同 retain;
  • 但是在修饰 block 时,strong 相当于 copy,而 retain 相当于 assign。
retian


  • MRC 下利用,ARC 下基本利用 strong;
  • 修饰强引用,保留新值,释放旧值,再设置新值,同时将新对象的引用计数加 1;
  • setter 方法的实现是 release 旧值,retain 新值,用于 OC 对象范例。
copy

setter 方法的实现是 release 旧值,copy 新值。用于 NSString、NSArray、NSDictionary 是为了包管赋值后是一个不可变对象,以免遭外部修改而导致不可预期的结果。
strong与copy

如果属性声明中指定了copy特性,合成方法会利用类的copy方法
类似点:用于修饰标识拥有关系的对象
差别点:strong的赋值是多个指针指向同一个地点,而copy的复制就是每次会在内存中复制一份对象,指针指向差别的地点。
strong与copy可以理解为深浅拷贝的区别
补充

属性关键字格式

推荐按照下面的格式来界说属性
  1. @property (nonatomic, readwrite, copy) NSString *name;
复制代码
属性的修饰符应该按照上面的顺序排列:原子操作、读写权限、内存管理
ARC下@property的默认属性

对于基本数据范例:atomic、readwrite、assign
对于普通的Objective-C对象:atomic、readwrite、strong

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表