版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.09.07 |
前言
不管ARC还是MRC都有引用计数,不同的是MRC的引用计数需要程序员自己管理,而ARC(iOS5及iOS5以后)的引用计数程序会自动帮助管理引用计数。下面就研究一下引用计数相关的几个问题。感兴趣的可以看我上面写的几篇。
1. 引用计数相关几个问题(一) —— alloc init 引用计数
问题提出
NSString有很多的实例化方法,那么这些方法在实例化的过程中,引用计数是如何变化的呢,下面我们就研究这个问题,同时给出测试过程与结果。
问题验证
测试1: [[NSString alloc] init];
- (void)demoAllocInitMethod
{
NSString *obj = [[NSString alloc] init];
NSLog(@"retainCount = %ld", obj.retainCount);
}
下面看测试结果
2017-09-07 10:54:49.974265+0800 JJOC[2516:1521721] retainCount = -1
测试2: - (instancetype)initWithFormat:(NSString )format, ...
- (void)demoAllocInitFormat
{
NSString *obj = [[NSString alloc] initWithFormat:@"%@", @"hello world"];
NSLog(@"retainCount = %ld", obj.retainCount);
[obj retain];
NSLog(@"retainCount = %ld", obj.retainCount);
[obj release];
NSLog(@"retainCount = %ld", obj.retainCount);
}
下面看测试测试结果
2017-09-07 10:58:37.129659+0800 JJOC[2522:1522579] retainCount = 1
2017-09-07 10:58:37.129715+0800 JJOC[2522:1522579] retainCount = 2
2017-09-07 10:58:37.129728+0800 JJOC[2522:1522579] retainCount = 1
测试3:- (instancetype)initWithString:(NSString )aString
- (void)demoAllocInitWithString
{
NSString *obj = [[NSString alloc] initWithString:@"hello world"];
NSLog(@"retainCount = %ld", obj.retainCount);
NSLog(@"retainCount = %lu", (unsigned long)obj.retainCount);
[obj retain];
NSLog(@"retainCount = %ld", obj.retainCount);
NSLog(@"retainCount = %lu", (unsigned long)obj.retainCount);
[obj release];
NSLog(@"retainCount = %ld", obj.retainCount);
NSLog(@"retainCount = %lu", (unsigned long)obj.retainCount);
}
看输出结果
2017-09-07 11:00:55.538982+0800 JJOC[2526:1523224] retainCount = -1
2017-09-07 11:00:55.539026+0800 JJOC[2526:1523224] retainCount = 18446744073709551615
2017-09-07 11:00:55.539039+0800 JJOC[2526:1523224] retainCount = -1
2017-09-07 11:00:55.539049+0800 JJOC[2526:1523224] retainCount = 18446744073709551615
2017-09-07 11:00:55.539059+0800 JJOC[2526:1523224] retainCount = -1
2017-09-07 11:00:55.539071+0800 JJOC[2526:1523224] retainCount = 18446744073709551615
测试4:直接赋值
- (void)demoString
{
NSString *obj = @"hello world";
NSLog(@"retainCount = %ld", obj.retainCount);
NSLog(@"retainCount = %lu", (unsigned long)obj.retainCount);
[obj retain];
NSLog(@"retainCount = %ld", obj.retainCount);
NSLog(@"retainCount = %lu", (unsigned long)obj.retainCount);
[obj release];
NSLog(@"retainCount = %ld", obj.retainCount);
NSLog(@"retainCount = %lu", (unsigned long)obj.retainCount);
}
下面看输出结果
2017-09-07 11:12:19.999139+0800 JJOC[2529:1524439] retainCount = -1
2017-09-07 11:12:19.999185+0800 JJOC[2529:1524439] retainCount = 18446744073709551615
2017-09-07 11:12:19.999198+0800 JJOC[2529:1524439] retainCount = -1
2017-09-07 11:12:19.999208+0800 JJOC[2529:1524439] retainCount = 18446744073709551615
2017-09-07 11:12:19.999218+0800 JJOC[2529:1524439] retainCount = -1
2017-09-07 11:12:19.999228+0800 JJOC[2529:1524439] retainCount = 18446744073709551615
结论:从上面的几个方法中,我们可以看到,方法- (instancetype)initWithFormat:(NSString *)format, ...
实例化会引起引用计数的变化,其他的实例化方法不会,究其原因,应该是其他的都是实例化一个字符串常量,系统不会释放,所以不用管理引用计数,而format
方法中可以添加很多其他类型作为参数,需要管理引用计数。
后记
未完,待续~~~