NSString中initWithString和initWithFormat的区别

来源:互联网 发布:淘宝大学商学院杭州 编辑:程序博客网 时间:2024/06/08 07:50

NSString * str =[[NSString alloc] initWithString:@"this is from initWithString function"];

NSLog(@"this is from [[NSString alloc] initWithString] m_addr is %ld retainCount is %i", str, [str retainCount]);

[str release];

[str release];

[str release];

NSLog(@"this is from [[NSString alloc] initWithString] m_addr is %ld retainCount is %i", str, [str retainCount]);

 

str = [[NSString alloc] initWithFormat:@"this is from initWithFormat function"];

NSLog(@"this is from [[NSString alloc] initWithFormat] m_addr is %ld retainCount is %d", str, [str retainCount]);


下面是LOG的结果:
 this is from [[NSString alloc] initWithString] m_addr is 12356 retainCount is 2147483647

 this is from [[NSString alloc] initWithString] m_addr is 12356 retainCount is 2147483647

 this is from [[NSString alloc] initWithFormat] m_addr is 82076688 retainCount is 1


 this is from [[NSString alloc] initWithString] m_addr is 12356 retainCount is 2147483647

 this is from [[NSString alloc] initWithString] m_addr is 12356 retainCount is 2147483647

 this is from [[NSString alloc] initWithFormat] m_addr is 78748112 retainCount is 1


 this is from [[NSString alloc] initWithString] m_addr is 12356 retainCount is 2147483647

 this is from [[NSString alloc] initWithString] m_addr is 12356 retainCount is 2147483647

 this is from [[NSString alloc] initWithFormat] m_addr is 78777072 retainCount is 1


我将上面这段测试代码调用了三次,得到以上的LOG结果。顺便得出这么几条结论。对于不对,请大家鉴定。
1.从两个变量的地址看,两个变量的地址差据较大。前者的地址非常靠前。
2.从release看,前者无论被release多少次,都不会被释放,而且的值不变,而后者只要release一次,变量即消亡。
3.前者的releaseCount= NSIntegerMax,而NSIntegerMax ==INT_MAX ,而 UINT_MAX== (INT_MAX * 2U + 1U)
U是指无符号整型,而我们默认的int和NSInteger是有符号的,在32位系统中,NSIntegerMax=0X7FFFFFFF,对其乘以2U,即一次向左挪一位。结果为0XFFFFFFFE,再加1U为0XFFFFFFFF,即无符号的最大值。
然后根据苹果官方对于retainCount方法的描述:

retainCount

Returns the receiver’s reference count. (required)

- (NSUInteger)retainCount
Return Value

The receiver’s reference count.

Discussion

You might override this method in a class to implement your own reference-counting scheme. For objects that never get released (that is, their release method does nothing), this method should return UINT_MAX, as defined in <limits.h>.

小生窃以为,此处的UINT_MAX和NSIntegerMax是一样的,都是表示所在类型的最大值。所以,initWithString这个方法初始化后的对象是不可能被release的或者说,它的release方法啥也不干。

验证了上面的分析2.因为他不可能被release的或者说,它的release方法啥也不干,所以我们调用无数次release都没有起到预先想想的作用。

为什么会导致这样的情况呢?

我们再次把目光转向地址。眼尖的同学可能会看到initWithString申请的地址每次都是一样的,而initWithFormat的地址每次都不一样,这个说明什么?

说明initWithString的地址是静态的,而initWithFormat是动态的。为什么前者是静态的,而后者是动态的?

结合上面关于retainCount的分析,小生窃以为initWithString的地址申请是在编译是进行的,这样才能说明为什么它的地址空间如此靠前。只有在编译是进行的,他才是静态的。

对于initWithString生成的对象,对其进行dealloc时,程序会报错(这里就不贴LOG了)。而后者initWithFormat不会报错。这进一步验证了initWithString生成的是静态对象,而initWithFormat是动态的。


结论:initWithString生成的对象是在编译是申请地址空间,而且在程序中不能释放,不建议使用。


0 0
原创粉丝点击