NSString的内存分配及管理

本文详细介绍了在Objective-C中初始化NSString的三种方法:直接赋值、类函数初始化和实例方法初始化,并探讨了不同初始化方式下字符串的内存分配及引用计数情况。

本文参考了这篇文章,主要做了补充说明:http://www.cnblogs.com/hellocby/archive/2012/08/23/2652201.html

生成一个NSString类型的字符串有三种方法:

方法1.直接赋值:    NSString *testStr1 = @"a";

方法2.类函数初始化生成:     

    NSString *testStr2 = [NSString stringWithString:@"b"];

    NSString *testStr3 = [NSString stringWithFormat:@"c"];

 方法3.实例方法初始化生成: 

    NSString *testStr4 = [[NSString alloc] initWithString:@"d"];

    NSString *testStr5 = [[NSString alloc] initWithFormat:@"e"];

首先查看它们的地址和引用计数:

2012-10-11 17:35:25.601 StringDemo[8514:11303] test1Address:0x4698

2012-10-11 17:35:25.601 StringDemo[8514:11303] test2Address:0x46a8

2012-10-11 17:35:25.602 StringDemo[8514:11303] test3Address:0x746c820

2012-10-11 17:35:25.602 StringDemo[8514:11303] test4Address:0x46c8

2012-10-11 17:35:25.603 StringDemo[8514:11303] test5Address:0x7455990

 

2012-10-11 17:35:25.585 StringDemo[8514:11303] test1:4294967295

2012-10-11 17:35:25.586 StringDemo[8514:11303] test2:4294967295

2012-10-11 17:35:25.596 StringDemo[8514:11303] test3:1

2012-10-11 17:35:25.600 StringDemo[8514:11303] test4:4294967295

2012-10-11 17:35:25.600 StringDemo[8514:11303] test5:1

 

从上可以看出,test1,test2,test4都是在一个内存区域,也就是上文所说的常量内存区。test3,test5在一个内存区,也就是堆区。

这里就有一个疑问:[NSString alloc] initWithString:@"d"这种方式初始化的字符串,也就是test4.应该是位于堆区的,但为什么会跑到常量内存区来呢?据说是因为xcode对这种方式做了处理,还包括[NSString stringWithString:@"b"]这种方式,这两种初始化字符串都等同于@"ddd"了。所以说test2,test4都同等于test1了。

还有,对于NSString *testStr3 = [NSString stringWithFormat:@"c"];这种初始化的字符串,只要一写release语句就会挂掉,但其它的都不会挂掉,test1,test2,test4好理解,因为release本来就不会起作用;但testStr5无论release多少次也不会挂掉,只会在控制台报警告:malloc: *** error for object 0x744d650: double free*** set a breakpoint in malloc_error_break to debug。这个猜测应该是也xcode做了优化吧。

对现在4.4之后的编译器,NSString *testStr2 = [NSString stringWithString:@"b"];这种写法会报警告了:Using 'stringWithString' with a literal is redundant。也就是说这种写法是多余的了,它给的建议是用=@"b"这种方式来代替了。

小结下吧:

对NSString的初始化方法,对于test1,test2,test4这三种的话建议用=@“字符串”来使用,因为本来就是一样的。test3,test5这两种的话,建议用texst3这种,方便点,不用管内存问题,系统自已管理。


### Beehive框架中的内存管理机制 在探讨Beehive框架的内存管理实现方式及其优化技巧时,可以从几个核心方面入手。 #### 减少大块内存使用 为了有效控制资源消耗并提高性能,在设计和开发过程中应尽可能减少一次性申请的大块连续内存空间。对于Beehive而言,这意味着开发者应当评估哪些组件确实需要大量数据结构支持,并寻找替代方案来分摊这些需求[^1]。 #### 降低内存峰值 通过合理规划程序运行期间不同阶段所需的临时存储量,可以显著减小应用程序的最大占用RAM大小。例如,在处理大规模数据集或者执行复杂计算任务之前先清理不再使用的变量;利用`@autoreleasepool{}`包裹短期存在的对象创建过程以加速释放无用实例所占的空间。 #### 避免内存泄漏 确保所有动态分配出来的指针都能得到妥善回收是防止发生此类错误的关键所在。这不仅涉及到遵循Objective-C中常见的ARC(自动引用计数)规则,还包括对外部库函数调用返回的结果进行适当处置——特别是那些基于C语言API的部分。 #### 处理内存警告 当设备报告低内存状况时,应该立即响应采取措施减轻负担。比如暂停某些非必要的后台操作、提前卸载不可见视图控制器内的图片缓存等。此外还可以考虑注册监听通知中心发布的UIApplicationDidReceiveMemoryWarningNotification事件以便及时作出调整动作。 #### 特定于Beehive的技术细节 针对该特定框架本身,则可能还会有一些额外的最佳实践建议: - **复用大尺寸的对象池**:类似于UITableViewCells的做法,如果存在频繁构建销毁相似类型的大型实体的话,建立一个可重复利用的小型集合会很有帮助。 - **采用延迟加载策略**:只有当真正需要用到某个昂贵资源的时候才去初始化它,这样可以在启动初期节省不少开销。 - **选用更合适的容器类型**:像NSCache相比NSMutableDictionary更适合做键值映射表因为前者具备更好的淘汰算法能更好地适应不断变化的工作负载情况;而NSPurgableData则允许随时丢弃不重要的字节流从而腾出更多可用容量给更重要的部分. ```objc // 示例代码展示如何设置自定义cell以利于重用 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"MyCustomCell"; MyCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } // Configure the cell... return cell; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值