NSString中initWithString和initWithFormat的区别

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值