黄金法则
凡是通过alloc、init、copy、mutableCopy、retain进行创建的对象,都要使用release或autorelease进行释放。
- 自己生成的对象,自己持有
- 不是自己生成的对象,也可以持有
- 持有的对象在不在需要时候时,释放对象
- 非自己持有的对象,不需要释放
Strong
强引用,持有对象,对象的retainCount+1。当对象没有Strong指向时,将会被释放。
声明对象时,默认Strong
@property (strong, nonatomic) UIWindow * window;
NSString类型的属性,最终可能指向的是NSMutableString,为了防止源字符串的修改引起变化,最好是采用copy来修饰
##用在可变字符串时是深拷贝:##
//属性是iOS管理变量数据存取的方法
@property (nonatomic, strong) NSString *name;
@property (nonatomic, copy) NSString *meng;
@end
@implementation ViewController
-(void)viewDidLoad {
[super viewDidLoad];
[self testCopyAndStrong];
//[self testString];
}
-(void)testCopyAndStrong {
NSMutableString *str = [[NSMutableString alloc] initWithString:@"meng"];
self.meng = str;
self.name = str;
[str appendString:@"zhiqi"];
//&打印指针的地址,没有&则是打印指针所指向对象的地址
NSLog(@"%p, %p", str, &str);
//strong特性,指针地址不同,但是指针所指向对象的地址相同,是浅拷贝(地址拷贝)
NSLog(@"%p, %p", self.name, &_name); //copy特性,指针地址不同,指针所指向的对象的地址也不同,是深拷贝(内容拷贝)
NSLog(@"%p, %p", self.meng, &_meng);
NSLog(@"%@", str);
//self.name打印出mengzhiqi,可见strong特性只是把指针所指向对象的地址拷贝了
NSLog(@"%@", self.name);
NSLog(@"%@", self.meng);
}

- 对于不可变对象:strong和copy修饰,都是浅拷贝, 当对源数据修改时并无影响,用哪个都可以.
- 对于可变对象:strong浅拷贝,copy深拷贝.
- 如果不希望数据收到源数据的修改而影响就用copy.反之用strong
- 对可变对象修饰:一定要用strong. 因为copy返回的是不可变对象.
weak
弱引用,不会引起引用计数的变化;当对象被释放时,所有指向对象的弱引用指针会被置为nil,防止野指针。
给nil发送消息时,会直接return,不会crash。
weak原理
对象的SideTable中有一个Weak表,以对象的内存地址为key,value为指向该对象的指针数组。
当对象销毁时,通过对象的内存地址找到所有弱引用的指针并且只为nil。
@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
assign
assign 纯粹指向对象,不会引起引用计数的变化,当对象被释放时,指针不会被置为nil,仍然指向原地址,容易造成野指针。
所以assign一般都用来指向基础类型的变量,例如 int float bool struct等值类型。
值类型会被放入栈中,遵循先进后出的原则,由系统维护
引用类型会被放入堆中,需要手动维护(MRC)或者ARC维护
深copy浅copy
深拷贝就是内容拷贝,浅拷贝就是指针拷贝。本质区别在于:
- 是否开启新的内存地址,深copy会开辟新的内存空间
- 是否影响内存地址的引用计数,浅copy会使对象的引用计数+1
特点
Copy的目的是建立副本,同时修改原始对象和复本不会互相干扰
copy和mutableCopy存在的原因: 尽可能的节省内存开销.
- 对于不可变类型的copy,为浅copy,对象引用计数+1。
- 对可变类型的copy,为深copy,对象为不可变对象。
image.png
-对对象做mutableCopy操作,都为深拷贝,拷贝对象也会变为可变类型。
-对于容器类型(NSArray、NSDictionary等),深拷贝也仅是拷贝容器本身,对容器里面的元素只做浅拷贝。
自定义copy
- 遵循copy协议<NSCopying, NSMutableCopying>,
- 重写copyWithZone、mutableCopyWithZone方法
atomic 与nonatomic
对atomic修饰的属性的setter、getter方法添加了原子锁,保证set、get操作的完整性,也就是下一次的set、get操作必须等到上一次的set、get操作完成之后才能执行。
因为atomic添加了原子锁,会增加开销,运行速度更慢,在不需要保证set、get操作的完整的情况下,所以一般都使用nonatomic。
atomic不能完全保证线程安全
只能保证set、get操作的完整性,当开启多个线程执行多个set、get操作时,无法保证执行的顺序。
另外如数组除了set、get操作外还有remove的操作。
ios其他关键字
nullable: 表示修饰的属性或参数可以为空
nonnull:非空,表示修饰的属性或参数不能为空
注意:nonnull,nullable只能修饰对象,不能修饰基本数据类型
null_resettable: get方法:不能返回为空,set方法可以为空
null_unspecified:不确定是否为空
网友评论