博客> 内存管理之属性参数与变量关键字
内存管理之属性参数与变量关键字
2018-09-24 15:01 评论:0 阅读:1053 zheng_0418
ios Objective-C

前言

自从Apple官方SDK中,引入了ARC的概念后,在iOS开发时的内容管理变得不在是难题,原来的手动管理内容的工作全部交由编译器来做。

ARC(Atomic Reference Count),简述就是自动引入计数,而我们这篇文章主要叙述的也是Objective-C语言中,影响“引用计数”的属性参数和变量关键字。

初始化实例

在没有引入ARC时,使用@property关键字来生成属性的getterssetters方法,有几个可选的参数:assign(默认),retaincopy。这几个参数主要影响的也是生成属性的setters方法。举例Person类有个属性为NSString类型的card,示例代码:

1)Person person = [[Person alloc] init];
2)NSString *cardText = @"number";//@"number"堆内存地址:0X668901,引用计数为1,cardText指针地址:0X102221;
3)person.card = cardText;

assign

@property (nonatomic, assign) NSString *card;

assign参数,对于第三行的属性赋值来说就是简单赋值,不会更改"number"堆内存的引用计数,而且person.card指针的地址和cardText指针地址也是相同的。总结来说,就是一个简单地指针赋值。所以person.card的指针地址也是0X102221,指向的内存地址也是0X668901,而内存地址的引用计数仍然为1。

retain

@property (nonatomic, retain) NSString *card;

retain参数,对于第三行的属性赋值来说,就要释放掉person.card以前的内存值,而将开辟新的指针地址,来指向"number" 。所以person.card的指针地址将会变成新的地址,而指向的内容地址就是0X668901,而"number"堆内存的引用计数为2。

Copy

@property (nonatomic, copy) NSString *card;

顾名思义,copy参数,就是释放掉旧值,然后新建一块内存。对于第三行的赋值来说就是将"number"拷贝过去,所以person.card的指针地址将会变成新的地址,而person.card指向的堆内存地址也会变成新的地址,而"number"堆内存的引用计数仍然为1。这里额外说明一点,copy参数对于NSString类型的变量会拷贝堆内存的内容,而对于NSArray,NSDictionary等数据类型的变量时,拷贝的也是指针,就是我们所谓的“浅复制”。

ARC(weak、strong)

在Apple官方SDK引入ARC以后,我们就需要在ARC项目中,使用weakstrong参数来代替之前的参数,weak就相当于之前的assign,不同的是当weak类型的指针不使用一块堆内存时,weak类型的指针会置为nil,而较于之前使用assign的好处,就在于使用assign声明的指针不使用一块堆内存时,无法知道其他人是否还会使用,所以内存无法随着指针一起自动释放掉。strong就相当于retain,而默认的参数就是strong,比如第二行的声明,cardText指针的类型也是strong类型。强引用和弱引用的区别就在于当一块堆内存没有任何强指针指向时,就会释放掉内存,并且清除掉所有的弱指针。在iOS开发中,唯一一种使用weak声明指针的情况,就是要避免“retain cycle”,也就是一个父类retain一个子类,而一个子类又retain了父类,造成内存无法释放。

block关键字

除了使用@property关键字声明属性时的几个参数可以影响内存管理之外,Objective-C语言也提供了一些关键字,来帮助我们管理一些局部变量:

  1. __strong 是缺省的关键词。
  2. __weak 声明了一个可以自动 nil 化的弱引用。
  3. __unsafe_unretained 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
  4. __autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。
收藏
1
sina weixin mail 回到顶部