版权声明:本博客主要记录学习笔记和遇到的一些问题解决方案,转载请注明出处! https://blog.csdn.net/u010982507/article/details/82930817
Cocoa
中提供了一个机制来实现上图中的逻辑模型,它被称为引用计数
(reference counting
)或保留计数
(retain counting
)。引用计数的数值表示对象有几个对象在使用它。实现原理是:
- 每一个对象都拥有一个引用计数(
retain count
) - 当对象被创建的时候,引用计数的值是1
- 当发送
retain
消息时,该对象的引用计数加1,该对象的引用计数为2 - 当向这个对象发送
release
消息时,该对象的引用计数减1 - 当一个对象的引用计数为0时,系统自动调用
dealloc
方法,销毁该对象
测试示例
- 创建
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@end
- 创建
Person.m
#import "Person.h"
@implementation Person
// 重写dealloc方法
- (void) dealloc
{
NSLog(@"Person dealloc");
[super dealloc];
}
@end
- 在main方法中调用
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[Person alloc] init];
NSLog(@"person的引用计数:%ld",[p retainCount]); // 打印结果1
[p retain]; // 保留引用
NSLog(@"person的引用计数:%ld",[p retainCount]); // 打印结果2
[p release]; // 释放引用
NSLog(@"person的引用计数:%ld",[p retainCount]); // 打印结果1
[p release]; // 打印结果Person dealloc,调用的是dealloc方法
}
return 0;
}
使用问题
1、 dealloc重写报错,retainCount方法无效
- error log
'retainCount' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'retainCount'
- 解决方法
在Bulid Settings
中搜索Objective-C
,找到Automatic Reference Counting
,设置为No
。
参考文章
https://blog.csdn.net/wengyupeng/article/details/52005436#commentsedit
https://blog.csdn.net/iOSbird/article/details/50684325
ARC
是iOS5.0
以后才支持,iOS7.0
以后,强制使用ARC
。在xcode中ARC Automatic Refercences Counting
设置为YES
。- 原理:依然使用引用计数器来管理内存,只是引用计数器的操作方式不同,由程序员发送消息转换为编译器帮我们发送消息,会在合适的位置自动加入
retain、release、autorelease
消息来进行计数管理,ARC
是一种编译期语法。 - 使用
ARC
:在ARC
中,程序中不能出现retain、release、autorelease
在ARC中,程序不能在dealloc
方法中显示调用父类的dealloc
方法,一切在MRC
中和内存相关的操作,ARC
中都不能使用。 - 强引用:在程序中定义的引用,默认就是强引用,所谓的强引用指向一个对象时,对象的引用计数器会自动加1,当引用超出作用域,对象的引用计数器自动减1。
定义强引用:__Strong Student* stu = [[Student alloc] init];
当一个对象被引用指向时,此对象会隐式的retain
一次,当强引用超出作用域时,指向的对象会隐式的release
一次,引用在使用的时候,会根据作用域的范围,自动做加1减1操作 - 弱引用:
__weak Student* stu = [[Student alloc] init];
仅仅就是指向对象,当一个弱引用指向的对象,未销毁时,向对象发送消息,会自动变为强引用 当一个弱引用指向的对象被销毁时,弱引用本身会自动的赋值为nil
。 - 定义属性的时候,内存管理的描述
@property(nonatomic,strong)
@property(nonatomic,weak)
修改arc
为yes
方法:点击项目名称->在搜索框输入arc->
找到Object-C Automatic Refercences Counting
修改为yes
。 - 其他修饰关键字
@property(nonatomic,__unsafe__unretained)int age;__unsafe__unretained
等同于assign
,功能和weak
几乎一样,唯一的不同,没有"zeroing weak reference"
,通常用在基本数据类型__autoreleaseing
用在方法的返回值,将返回值的对象放入到自动释放池中。 dealloc
方法在ARC
中,dealloc
方法不允许调用父类的dealloc
方法,当然也不允许向任何对象发送release
消息,所以说dealloc
方法几乎不用,在一些特殊情况下需要重写dealloc
方法:
1、在类中使用了C
语言中的函数malloc
分配内存。
2、在类中使用了C++
语言中的函数new
等方式创建内存空间
此时需要在dealloc中对这些特殊的空间进行释放。- 声明引用自动置空, 在
ARC
下,如果定义了一个引用没有赋值,编译会自动的初始化设置引用为空值,Student* stu;
为了尊重C
语言的规范,基本数据类型没有初始化,依然是垃圾值。 MRC
和ARC
的混用,把MRC
的代码转换成ARC
的代码,删除内存管理操作(手动)xcode
提供了自动将MRC
转换成ARC
的功能,操作菜单栏edit -> Refacoto
r(重构)->Convert to Objective-C ARC
。 在ARC
项目中继续使用MRC
编译的类,在编译选项中标识MRC
文件即可-fno-objc-arc
,在MRC
项目中继续使用ARC
编译的类在编译选项中标识MRC
文件即可-fobjc-arc
。