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方法。
浙公网安备 33010602011771号