iOS点点滴滴iOSiOS学习

iOS内存管理探底

2017-11-13  本文已影响15人  踏云小子

一、引用计数(保留计数)

iOS的内存管理主要是依赖引用计数,so,我们扯扯这个的工作原理:


1707017-089e69ea2340eaa6.png

二、属性修饰方法assign,weak,strong,retain,copy

image.png
2.1 retain, strong其实一个意思
2.2 copy, strong区别
#import <Foundation/Foundation.h>

@interface XYPerson : NSObject

@property (nonatomic,copy) NSString * name;

@property (nonatomic,strong) NSString * StrongName;

@end

测试如下

NSMutableString *name = [NSMutableString stringWithFormat:@"will is so"];
self.name = name;
self.StrongName = name;
[name appendString:@" handsome"];
NSLog(@"%@ \n %@", self.name, self.StrongName);

打印如下:


image.png

很明显,StrongName内容发生了变化

拓展

经常有这样面试题
用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
答:是因为NSString、NSArray、NSDictionary有对应的可变类型NSMutableString、NSMutableArray、NSMutableDictionary,如果属性被这些可变类型赋值了,那么会导致属性无意变动,为避免这些,使用copy;如果使用strong关键字,会导致属性无意变动

2.3 strong, weak区别
区别
应用
#define RCLog(obj){if (obj){printf("retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(obj)));}else{printf("null \n");}}

RCLog(self);        
[self block:^{
    self.strongPoint = [NSDate date];
}];
RCLog(self);

打印:

retain count = 7
retain count = 8

打印引用计数,发现+1了,这里self持有block,而block又持有self,导致了引用循环,我们用__weak来解决:

RCLog(self);
__weak typeof(self) weakself=self;
[self block:^{
    weakself.strongPoint = [NSDate date];
}];
RCLog(self);

打印:

retain count = 7
retain count = 7

有的block用__strong来修饰对象,是为了防止对象引用时,不会已经是nil了,举个例子:

RCLog(self);
__weak typeof(self) weakself=self;
[self block:^{
    __strong typeof (self) strongself = weakself;
    strongself.strongPoint = [NSDate date];
}];
RCLog(self);

打印:

retain count = 7
retain count = 7
2.4 assign, weak区别
#import <Foundation/Foundation.h>

@interface XYPerson : NSObject

@property (nonatomic, strong) id strongPoint;
@property (nonatomic, weak) id weakPoint;
@property (nonatomic, assign) id assignPoint;

@end

测试如下:

self.strongPoint = [NSDate date];
self.weakPoint = self.strongPoint;
self.assignPoint = self.strongPoint;
    
self.strongPoint = nil;

打断点,当strongPoint置为nil后,weakPoint也置为nil,而assignPoint则出现野指针


image.png

三、对象修饰方法__weak,__strong,__unsafe_unretained

3.1 __weak

弱引用,其存亡不决定所指对象的存亡,若所指对象被其他强引用指向,强引用置为nil,则其所指对象也置为nil

3.2 __strong

强引用, 默认就是__strong,其存亡直接决定所指对象的存亡,在赋值时对对象进行retain操作,使引用计数+1

__strong NSObject *obj1=[NSObject new];
    
__strong NSObject *obj2 = obj1;
    
obj1=nil;

NSLog(@"%@,%@",obj1,obj2);

打印如下:

(null),<NSObject: 0x60000001f6c0>
__strong NSObject *obj1=[NSObject new];
    
__weak NSObject *obj2 = obj1;
    
obj1=nil;

NSLog(@"%@,%@",obj1,obj2);

打印如下:

(null),(null)
3.3 __unsafe_unretained

__unsafe_unretained与__weak类似,只不过若所指对象被其他强引用指向,且强引用置为nil,则其所指对象不置为nil

上一篇 下一篇

猜你喜欢

热点阅读