iOS开发笔记之三十六——开发中内存管理的使用技巧汇总
来源:互联网 发布:js获取所有data属性 编辑:程序博客网 时间:2024/05/23 12:35
IOS自动有了ARC机制后,以及主流iphone设备不断扩大的内存,让开发者可以不像以前那样严格的考虑内存问题了。但是作为一个开发者,我们还是要尽可能的要写出合理使用内存的程序,尤其在调用某些第三方、开源的API、加载图片等资源文件、处理音视频等场景时,建议大家还是多多注意下。因为ARC下一旦出现内存问题,将更加难以定位与发现,有时即使leak工具也无法发现;此文便是汇总了开发中以及自己在实际的文档搜索中,总结的关于内存管理的一些使用技巧,便于查阅。
1、加载图片的方法:
[UIImage imageNamed:]只适合与UI界面中的贴图的读取,较大的资源文件应该尽量避免使用,用UIImage加载本地图像最常用的是下面三种:
(1) 用imageNamed方法:
[UIImage imageNamed:ImageName];
(2) 用 imageWithContentsOfFile 方法:
NSString *thumbnailFile = [NSString stringWithFormat:@"%@/%@.png", [[NSBundle mainBundle] resourcePath], fileName];
UIImage *thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
(3)用initWithContentsFile方法
UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath]
第一种方法为常见方法,利用它可以方便加载资源图片。用imageNamed的方式加载时,会把图像数据根据它的名字缓存在系统内存中,以提高imageNamed方法获得相同图片的image对象的性能。即使生成的对象被 autoReleasePool释放了,这份缓存也不释放。而且没有明确的释放方法。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存。第二种方法加载的图片是不会缓存的。得到的对象时autoRelease的,当autoReleasePool释放时才释放。第三种方法要手动release掉。不进行系统缓存。release后立即释放,一般用在封面等图比较大的地方。
2、滑动列表的时候,使用UITableView的reuse机制
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
}
dequeueReusableCellWithIdentifier 方法会把隐藏的界面拿来重用,这样节省很多资源。
3、要大量创建局部变量的时候,可以创建内嵌的autorelease pool来及时释放内存
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i, j;
for (i = 0; i < 100; i++ )
{
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
for (j = 0; j < 100000; j++ )
[NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
[loopPool release];
}
[pool release];
return 0;
}
4、循环引用带来的内存泄露。循环引用指两个对象相互引用了对方,从而导致谁也释放不了谁,导致内存泄露。例如声明一个delegate时,一般用assign而不是retain或者strong,因为delegate很容易引起循环引用。出现循环引用的场景还有block语句,例如:
self.myblock = ^{
[
self
doSomething];
};
__block TestCycleRetain *weakSelf =
self
;
self
.myblock = ^{
[weakSelf doSomething];
};
以下写法则不会出现循环引用:
//不会循环引用
__weak TestCycleRetain *weakSelf =
self
;
self
.myblock = ^{
[weakSelf doSomething];
};
//不会循环引用
__unsafe_unretained TestCycleRetain *weakSelf =
self
;
self
.myblock = ^{
[weakSelf doSomething];
};
参考资料:
(1)http://www.chengxuyuans.com/iPhone_IOS/67181.html
(2)http://www.cnbluebox.com/?p=255
- iOS开发笔记之三十六——开发中内存管理的使用技巧汇总
- IOS开发之Block的使用和内存管理
- iOS开发学习笔记三 —— 内存管理
- iOS开发UI篇—IOS开发中Xcode的一些使用技巧
- iOS开发UI篇—IOS开发中Xcode的一些使用技巧
- iOS开发UI基础—14IOS开发中Xcode的一些使用技巧
- iOS开发UI篇—IOS开发中Xcode的一些使用技巧
- iOS开发UI篇—IOS开发中Xcode的一些使用技巧
- IOS开发笔记之开发的一些技巧
- OS开发UI篇—IOS开发中Xcode的一些使用技巧
- iOS开发经验总结—内存管理
- iOS开发系列—内存管理
- iOS开发经验总结—内存管理
- iOS开发笔记1 - 内存管理
- IOS开发笔记20-OC内存管理
- iOS开发笔记之四十九——iOS开发中一些常用的路径
- IOS开发—block对外部变量的内存管理
- IOS 开发之UIImageView帧动画的内存管理
- 图像处理领域的国际会议及期刊
- cocos2d-x中的Jni使用(C++与Andriod方法互调)
- C语言运算符优先级
- Ubuntu更新出现 The system is running in low-graphics mode解决
- Appium Server源码分析之作为Bootstrap客户端
- iOS开发笔记之三十六——开发中内存管理的使用技巧汇总
- WAS6.1JNDI数据源配置测试代码
- Word Ladder
- 敲代码时的一些常用技巧
- Linux发展历程
- 移植MonkeyRunner的图片对比和获取子图功能的实现-Appium篇
- Leetcode: Intersection of Two Linked Lists
- LeetCode Sort List 解题报告
- Notification与AlarmManager相结合实现定时本地消息推送