首先搞清楚一个概念,地址:内存是由不少位组成的,每8位是一个字节,而每个字节都有一个名字(能够看做门牌号),这个名字就是这一字节内存的地址。atom
int a = 10; //在栈区,申请一块内存(4个字节,也就是32位),存放数字10,a是这块内存的别名。spa
a = 20; //a表明的是上面申请的4个字节的内存,也就是在这块内存 存放数字20,数字10被覆盖。指针
int *p = &a; //在栈区,申请一块内存,存放变量a的地址(&是取地址符,取的是a的4个字节中第一个字节的门牌号), p是这块内存的别名。而此时,这块内存中存放的是地址,因此此时p变量就是一个指针。(也就是说, 存放地址的内存的别名就是指针)code
*p = 30; //*是取值符,从p表明的地址开始,日后取够4个字节的内存,此时取到的就是a表明的内存。而后存放 数字30,因此,此时a表明的内存存放的是数字30。blog
OC内存管理内存
若是有过MRC开发经验,内存管理相对简单。可是如今不少刚入行一两年的iOS开发人员,基本都是ARC开发,对内存管理的理解就没那么透彻。因此,先写一个MRC环境下demo:开发
1 #import "ViewController.h" 2 3 #import "Person.h" 4 5 @interface ViewController () 6 7 @property (nonatomic,assign)Person *person;// ⚠️ 我这里 用的关键字是 assign 8 9 @end 10 11 @implementation ViewController 12 - (void)viewDidLoad { 13 14 self.person = [[Person alloc] init]; 15 16 NSLog(@"%zd",_person.retainCount);//结果是 2 17 18 [_person release]; 19 20 NSLog(@"%zd",_person.retainCount);//结果是 1 21 } 22 23 //我重写了setter方法 24 - (void)setPerson:(Person *)person{ 25 26 if (_person != person) { 27 [_person release]; 28 29 _person = [person retain]; 30 } 31 } 32 33 @end
由打印结果能够看出来,我虽然用的关键字是assign,可是当我使用self.person赋值的时候,仍是产生了强引用,和retain同样的效果。这是由于,我重写了setter方法。用关键字assign,他自动生成的setter方法应该是直接赋值it
- (void)setPerson:(Person *)person{内存管理
_person = person;io
}
我重写setter方法以后,其实就变成了强引用。因此,咱们在声明属性的时候,使用不一样关键字自动生成的setter方法的实现不一样。强弱引用是在setter方法里体现的。
如今,我把程序改一下:
@property (nonatomic,retain)Person *person;// 我这里 使用关键字 retain
@implementation ViewController
- (void)viewDidLoad {
_person = [[Person alloc] init];
NSLog(@"%zd",_person.retainCount);//结果是 多少。。。
}
结果是1,此时没有强引用,由于我赋值的时候,用的是_person,没有用到setter方法。