您的位置:首页 > 其它

NSString中initWithString和initWithFormat的区别

2015-12-12 17:21 399 查看
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生成的对象是在编译是申请地址空间,而且在程序中不能释放,不建议使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: