//
// main.m
// Oc-Day1
//
// Created by spare on 16/4/9.
// Copyright © 2016年 spare. All rights reserved.
//
//引用计数是Objective-C语言采用的一种内存管理技术,当一个对象被创建在堆上后,该对象的引用计数就自动设置为1,如果在其它对象中的对象成员需要持有这个对象时,则该对象的引用计数被加上1,此时如果该对象被释放,内存管理程序将首先把该对象的引用计数减1,然后判断该对象的引用计数是否为0,由于其它对象在持有该对象时将引用计数加了1,所以此时该对象的引用计数减1后不为0,则内存管理程序将不会释放该对象。直到持有该对象的其它对象也被释放时,该对象的引用计数再次减1,变为0时,该对象在堆上所占的存储空间才被释放。
//引用计数技术的使用能够实现对资源的自动管理。
//iOS5.0开始引入自动引用计数技术,iOS7.0以后则默认使用自动引用计数技术。自动引用计数技术,简称为ARC,由于ARC的出现,相对以前的方式被称为手动引用计数技术,简称为MRC。
#import <Foundation/Foundation.h>
#import "Integer.h"
//本案例是强制使用MRC(手动引用计数技术)来管理对象的引用计数的一个练习。由于iOS7.0以后使用Xcode创建的工程默认使用ARC(自动引用计数技术),所以需要强制转换回MRC。转换的方法如下步骤:
//首先,创建一个工程,然后选择“工程导航”中的“工程项”
//然后在右边窗口中选择Build Settings
//下一步选择All选项
//最后,向下滚动屏幕,找到Apple LLVM 5.1 – Language – Objective C中的Objective-C Automatic Reference Counting,将右边的选项选择为NO
int main(int argc, const char * argv[]) {
@autoreleasepool {
Integer *int1=[[Integer alloc]init];
NSLog(@"%ld",[int1 retainCount]);//1
Integer *int2 = int1;
//retainCount消息将得到对象int1当前的引用计数值。
NSLog(@"%ld", [int1 retainCount]);//1
// 由于此时有两个指针指向对象int1,int1的引用计数应该变为2。但在MRC下,要想将int1的引用计数值加1,必须手动添加retain消息才能实现。
// 对象int2发送消息retain,该消息会使int2指向的对象的引用计数加1,由于int2与int1共同指向一个对象,所以向对象int1发送retainCount消息,得到的值为2。
[int2 retain];
NSLog(@"%ld", [int1 retainCount]);//2
NSLog(@"%ld", [int2 retainCount]);//2
//在MRC下,要想将int1的引用计数值减1,必须手动添加release消息才能实现。
[int2 release];
NSLog(@"%ld", [int1 retainCount]);//1
NSLog(@"%ld", [int2 retainCount]);//1
// 向对象int1发送消息release,该消息会使int1指向的对象的引用计数减1,由于int1指向的对象的引用计数已经为1,再减1,将会变为0。此时int1所指向的对象被释放了。但是,如果此时向对象int1发送retainCount消息,得到的int1的引用计数值仍然为1,这是因为此时retainCount消息访问的int1的地址空间,是已经释放的空间,在释放前该空间的引用计数变量没有清0的缘故
[int1 release];
NSLog(@"%ld", [int1 retainCount]);//1
NSLog(@"%ld", [int2 retainCount]);//1
}
return 0;
}