c语言中 变量 和 指针 的区别:

首先搞清楚一个概念,地址:内存是由很多位组成的,每8位是一个字节,而每一个字节都有一个名字(可以看作门牌号),这个名字就是这一字节内存的地址。

  int a = 10;  //在栈区,申请一块内存(4个字节,也就是32位),存放数字10,a是这块内存的别名。

  a = 20;  //a代表的是上面申请的4个字节的内存,也就是在这块内存 存放数字20,数字10被覆盖。

  int *p = &a;  //在栈区,申请一块内存,存放变量a的地址(&是取地址符,取的是a的4个字节中第一个字节的门牌号),               p是这块内存的别名。而此时,这块内存中存放的是地址,所以此时p变量就是一个指针。(也就是说,                存放地址的内存的别名就是指针)

  *p = 30;  //*是取值符,从p代表的地址开始,往后取够4个字节的内存,此时取到的就是a代表的内存。然后存放                   数字30,所以,此时a代表的内存存放的是数字30。

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方法应该是直接赋值

- (void)setPerson:(Person *)person{

    _person = person;

}

我重写setter方法之后,其实就变成了强引用。所以,我们在声明属性的时候,使用不同关键字自动生成的setter方法的实现不同。强弱引用是在setter方法里体现的。

 

现在,我把程序改一下:

 

@property (nonatomic,retain)Person *person;// 我这里 使用关键字 retain 

 

@implementation ViewController

 

- (void)viewDidLoad {

 

    _person = [[Person alloc] init];

 

    NSLog(@"%zd",_person.retainCount);//结果是 多少。。。

 

}

 

结果是1,此时没有强引用,因为我赋值的时候,用的是_person,没有用到setter方法。