`
ydbc
  • 浏览: 721217 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

IOS 细节整理

 
阅读更多
Objective-C指针赋值时,retain count不会自动增加,需要手动retain

ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1

ClassA *obj2 = obj1; //retain count = 1

[obj2 retain]; //retain count = 2

[obj1 hello]; //输出hello

[obj1 release]; //retain count = 2 – 1 = 1

[obj2 hello]; //输出hello

[obj2 release]; //retain count = 0,对象被销毁

注意,如果没有调用[obj2 release],这个对象的retain count始终为1,不会被销毁,内存泄露


//


autorelease pool原理剖析。

1autorelease pool不是天生的,需要手动创立。只不过在新建一个iphone项目时,xcode会自动帮你写好。autorelease pool的真名是NSAutoreleasePool

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

2NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。

ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1,把此对象加入autorelease pool

3NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count1,那么release之后,retain count0,对象正式被销毁。如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,此对象依然没有被销毁,内存泄露。

4默认只有一个autorelease pool,通常类似于下面这个例子。

int main (int argc, const char *argv[])

{

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

// do something

[pool release];

return (0);

} // main

所有标记为autorelease的对象都只有在这个pool销毁时才被销毁。如果你有大量的对象标记为autorelease,这显然不能很好的利用内存,在iphone这种内存受限的程序中是很容易造成内存不足的。例如:

int main (int argc, const char *argv[])

{

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int i, j;

for (i = 0; i < 100; i++ )

{

for (j = 0; j < 100000; j++ )

[NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。

}

[pool release];

return (0);

} // main

运行时通过监控工具可以发现使用的内存在急剧增加,直到pool销毁时才被释放,你需要考虑下一条。

5Objective-C程序中可以嵌套创建多个autorelease pool。在需要大量创建局部变量的时候,可以创建内嵌的autorelease pool来及时释放内存。(感谢网友hhyytt和neogui的提醒,某些情况下,系统会自动创建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);

} // main



口诀。

谁创建,谁释放(类似于“谁污染,谁治理”)。如果你通过 alloc new copy 来创建一个对象,那么你必须调用release autorelease。换句话说,不是你创建的,就不用你去释放。
例如,你在一个函数中alloc生成了一个对象,且这个对象只在这个函数中被使用,那么你必须在这个函数中调用releaseautorelease。如果你在一个class的某个方法中alloc一个成员对象,且没有调用autorelease,那么你需要在这个类的dealloc方法中调用release;如果调用了autorelease,那么在dealloc方法中什么都不需要做。



范式。
范式就是模板,就是依葫芦画瓢。由于不同人有不同的理解和习惯,我总结的范式不一定适合所有人,但我能保证照着这样做不会出问题。

1创建一个对象。

ClassA *obj1 = [[ClassA alloc] init];

2创建一个autorelease的对象。

ClassA *obj1 = [[[ClassA alloc] init] autorelease];

3Release一个对象后,立即把指针清空。(顺便说一句,release一个空指针是合法的,但不会发生任何事情)

[obj1 release];

obj1 = nil;

4指针赋值给另一个指针。

ClassA *obj2 = obj1;

[obj2 retain];

//do something

[obj2 release];

obj2 = nil;

5在一个函数中创建并返回对象,需要把这个对象设置为autorelease

ClassA *Func1()

{

ClassA *obj = [[[ClassA alloc]init]autorelease];

return obj;

}



ARC基本规则

  • retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用
  • dealloc虽然可以被重载,但是不能调用[super dealloc]

由于ARC并不是GC,并需要一些规则让编译器支持代码插入,所以必须清楚清楚了这些规则后,才能写出健壮的代码。


arc就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。



分享到:
评论

相关推荐

    iOS应用逆向工程:分析与实战

    6.2.1 分析函数实现细节 132 6.2.2 验证分析结果 139 6.3 在GDB 中分析目标文件 142 6.3.1 跟踪代码执行流程 142 6.3.2 动态更改代码 147 6.4 小结 157 第四部分 实战篇 第7 章 实战1:去除...

    iOS QQ Demo

    整理的一个小demo。不过是demo,细节考虑的不全。但是逻辑在这。写的比较简单,没有做什么封装。比较易懂。但是拖拽动画,那一块,没有细化。

    iOS自动进行View标记的方法详解

    缘起 一切都源于我的上一篇博客,我写的是一篇 UITableViewCell...静下心来整理我的想法和寻找方案,大概的整理下了一个可行性的方案以及这个方案中需要使用到的步骤,其中一些细节没有在这个步骤中体现 获取水平的

    腾讯Bugly技术分享:JSPatch实现原理详解

    之前在博客上写过两篇JSPatch原理解析文章(12),但随着JSPatch的改进,有些内容已经跟最新代码对不上,这里重新整理成一篇完整的文章,对原来的两篇做整合和修改,详细阐述JSPatch的实现原理和一些细节,以帮助使用...

    Javaweb学生管理系统、超市管理系统、医院挂号系统、餐饮系统、电影院管理系统、双色球购买系统、银行系统、成绩管理系统

    J整合各类学生作业: 1)开发框架包含gui、swing,javaweb等 2)开发语言包含:java、python、ios、android等 3)包含各类作业案例: 学生管理系统、超市管理系统、医院挂号系统、餐饮系统、电影院管理系统、双色球...

    产品设计经验分享:6个输入框,47个设计点

    “乍一看到某个问题,你会觉得很简单,其实你并没有...设计分两步走,分别是信息架构设计和细节设计,细节再从默认状态、填写状态、反馈状态三个角度进行设计。以下是过程描述:也就是整理信息、规划步骤,把需要用户

    develop-tree-book:展示开发系统的书

    好记性不如烂笔头,此地将多年的学习与实践整理出一套笔记,尽可能用“大纲总结 + 细节深入”的方式,组织成一棵系统的软件开发知识树。原本计划采用思维导图的方式来记录和展示,但无奈内容太多,文件打开速度超慢...

    数据的秘密(下):如何分析数据?.pdf

    拿日活来说,我们可以再进一步进行分析, 比如: 日活中新用户所占的比例 日活中 iOS 和 Android 的各自占比 日活中大家集中活跃的时间段 日活中用户的会话(Session)次数分布,时长分布 日活中用户平均使用你的...

    大数据技术在银行的应用.pdf

    例如,在传统银行经营模式下,商业银行仅能 记录每次的银行卡消费信息,却无法实现实时的消费信息反馈,归 集整理; 在存款、 贷款风险管控过程当中,商业银行在记录了客户 消费和挑选产品的数据后,亦没有利用好这些非...

    深入理解Android:卷I--详细书签版

    CruiseYoung提供的带有详细书签的电子书籍目录 ... 深入理解Android:卷I(51CTO网站“2011年度最受读者喜爱的原创IT技术图书”) 基本信息 作者: 邓凡平 出版社:机械工业出版社 ISBN:9787111357629 ...

Global site tag (gtag.js) - Google Analytics