- 浏览: 709981 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
javenwong:
你好,我现在需要给一个Composite做圆角处理,不知道怎么 ...
SWT圆角窗口绘制 -
whao189:
回家了详细看看
Storyboard 解析 -
zhaoyubetter:
确实够麻烦
IOS 开发环境,证书和授权文件是什么? -
datawarehouse:
一直对这两个认为是一样的,现在学习了。
Oracle DB中的Schema -
yulanfeiyang:
顶,mark
下载音频,在IOS设备上播放
iPhone系统中的Objective-C的内存管理机制是比较灵活的,即可以拿来像C/C++一样用,也可以加个AutoreleasePool让它升级为半自动化的内存管理语言。当然,也不能拿JAVA虚拟机中的全自动化GC来比〜
一,引用计数是实例对象的内存回收唯一参考
引用计数(retainCount)是Objective-C管理对象引用的唯一依据。调用实例的release方法后,此属性减一,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。
它的内存管理API老简单老简单了,下面就是它主要操作接口:
1,alloc, allocWithZone,new(带初始化)
为对象分配内存,retainCount为“1”,并返回此实例
2,release
retainCount 减“1”,减到“0”时调用此对象的dealloc方法
3,retain
retainCount 加“1”
4,copy,mutableCopy
复制一个实例,retainCount数为“1”,返回此实例。所得到的对象是与其它上下文无关的,独立的对象(干净对象)。
5,autorelease
在当前上下文的AutoreleasePool栈顶的autoreleasePool实例添加此对象,由于它的引入使Objective-C(非GC管理环境)由全手动内存管理上升到半自动化。
二,Objective-C内存管理准则
我们可以把上面的接口按对retainCount的操作性质归为两类,
A类是加一操作:1,3,4
B类是减一操作:2,5(延时释放)
内存管理准则如下:
1,A与B类的调用次数保持一制
2,为了很好的保障准则一,以实例对象为单位,谁A了就谁B,没有第二者参与
三,对象的拥有者
面向对象领域里有个引用的概念,区别于继承,引用常被用来当做偶合性更小的设计。继承是强依赖,对吧。我们要降偶软件的设计,就要尽量减少对它的使用。但没有任何偶合的模块或功能是没有用的〜对吧,那我们只能多用引用了吧。一个实例拥有另一个实例的时候,我们称它为引用了另一个实例。
比如ClassA类的一个属性对象的Setter方法:
假设这个类的一个实例为'a',调用setMyArray后,我们就可以说a拥有了一个新的myArray实例,也可以说a引用了一个新的myArray实例。其中调用的retain方法,使myArray的retainCount加一,我们需要注意以下两个地方:
1,setMyarray方法中,在retain之前先release了旧实例一次
2,在本实例的dealloc方法中,本应该是要再次release当前实例的,但回头看看参考内存管理准则。它并不合理,对吧。。。多了一次release。这里比较推荐的做法是:
[myArray setMyArray:nil];
这样可以巧妙的使当前实例release而不出错(我们可以向nil发送消息〜其实它本身就是个整数0),并符合我们的内存管理准则。更主要的是,很简单,你不需要考虑过多的事情。
另外一个比较容易忽略而又比较经典的问题是实例变量的循环引用,Objective-C为此区分了,其实也相当相当的简单:
1,强引用,上面讲的就是强引用,存在retainCount加一。
2,弱引用,但凡是assign声明并直接用指针赋值实现的被称之为弱引用,不存在retainCount加一的情况。
四,AutoreleasePool使Objective-C成为内存管理半自动化语言。
如果仅仅是上面这些,很简单,对吧。但往往很多人都会迷糊在自动内存管理这块上,感觉像是有魔法,但其实原理也很简单〜
先看看最经典的程序入口程序:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
我们先把pool看成一个普通对象〜很简单,先是alloc,pool的retainCount为1。第三句release,retainCount为0,自动调用它的dealloc方法。它和任何其它普通对象没 任何区别。
魔法在哪里?
在声明pool后,release它之前的这段代码,所有段里的代码(先假设中间没有声明其它的AutoreleasePool实例),凡是调用了autorelase方法的实例,都会把它的retainCount加1,并在此pool实例中添1次此实例要回收的记录以做备案。当此pool实例dealloc时,首先会检查之前备案的所有实例,所有记录在案的实例都会依次调用它的release方法。
真对同一个实例,同一个Pool是可以多次注册备案(autorelease)的。在一些很少的情况化可能会出现这种需求:
我们调用了两次A类(retainCount加1的方法),使其retainCount为2,而接下来的两次autorelease方法调用,使其在pool中注册备案了两次。这里的pool将会在回收时调用此实例的两次release方法。使其retainCount降为0,完成回收内存的操作,其实这也是完全按照内存管理规则办事的好处〜
AutoreleasePool是被嵌套的!
池是被嵌套的,嵌套的结果是个栈,同一线程只有当前栈顶pool实例是可用的:
| pool_3 |
| --------- |
| pool_2 |
| --------- |
| pool_1 |
|_______|
其代码如下:
我们可以看到其栈顶是pool3,o的autorelease是把当前的release放在栈顶的pool实例管理。。。也就是pool3。
在生命周期短,产生大量放在autoreleasePool中管理实例的情况下经常用此方法减少内存使用,达到内存及时回收的目的。
AutoreleasePool还被用在哪里?
在上面的例子里,也可以看到,我们在执行autorelease方法时,并没有时时的进行release操作〜它的release被延时到pool实例的dealloc方法里。这个小细节使我们的Objective-C用起来可以在方法栈中申请堆中的内存,创建实例,并把它放在当前pool中延迟到此方法的调用者释放〜
http://www.cocoachina.com/bbs/read.php?tid-12760.html
一,引用计数是实例对象的内存回收唯一参考
引用计数(retainCount)是Objective-C管理对象引用的唯一依据。调用实例的release方法后,此属性减一,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。
它的内存管理API老简单老简单了,下面就是它主要操作接口:
1,alloc, allocWithZone,new(带初始化)
为对象分配内存,retainCount为“1”,并返回此实例
2,release
retainCount 减“1”,减到“0”时调用此对象的dealloc方法
3,retain
retainCount 加“1”
4,copy,mutableCopy
复制一个实例,retainCount数为“1”,返回此实例。所得到的对象是与其它上下文无关的,独立的对象(干净对象)。
5,autorelease
在当前上下文的AutoreleasePool栈顶的autoreleasePool实例添加此对象,由于它的引入使Objective-C(非GC管理环境)由全手动内存管理上升到半自动化。
二,Objective-C内存管理准则
我们可以把上面的接口按对retainCount的操作性质归为两类,
A类是加一操作:1,3,4
B类是减一操作:2,5(延时释放)
内存管理准则如下:
1,A与B类的调用次数保持一制
2,为了很好的保障准则一,以实例对象为单位,谁A了就谁B,没有第二者参与
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSObject *o = [[NSObject alloc] init]; //retainCount为1 [o retain]; //retainCount为2 [o release]; //retainCount为1 [o autorelease]; //retainCount为1 [pool release]; //retaincount为0,触发dealloc方法
三,对象的拥有者
面向对象领域里有个引用的概念,区别于继承,引用常被用来当做偶合性更小的设计。继承是强依赖,对吧。我们要降偶软件的设计,就要尽量减少对它的使用。但没有任何偶合的模块或功能是没有用的〜对吧,那我们只能多用引用了吧。一个实例拥有另一个实例的时候,我们称它为引用了另一个实例。
比如ClassA类的一个属性对象的Setter方法:
- (void)setMyArray:(NSMutableArray *)newArray { if (myArray != newArray) { [myArray release]; myArray = [newArray retain]; } }
假设这个类的一个实例为'a',调用setMyArray后,我们就可以说a拥有了一个新的myArray实例,也可以说a引用了一个新的myArray实例。其中调用的retain方法,使myArray的retainCount加一,我们需要注意以下两个地方:
1,setMyarray方法中,在retain之前先release了旧实例一次
2,在本实例的dealloc方法中,本应该是要再次release当前实例的,但回头看看参考内存管理准则。它并不合理,对吧。。。多了一次release。这里比较推荐的做法是:
[myArray setMyArray:nil];
这样可以巧妙的使当前实例release而不出错(我们可以向nil发送消息〜其实它本身就是个整数0),并符合我们的内存管理准则。更主要的是,很简单,你不需要考虑过多的事情。
另外一个比较容易忽略而又比较经典的问题是实例变量的循环引用,Objective-C为此区分了,其实也相当相当的简单:
1,强引用,上面讲的就是强引用,存在retainCount加一。
2,弱引用,但凡是assign声明并直接用指针赋值实现的被称之为弱引用,不存在retainCount加一的情况。
四,AutoreleasePool使Objective-C成为内存管理半自动化语言。
如果仅仅是上面这些,很简单,对吧。但往往很多人都会迷糊在自动内存管理这块上,感觉像是有魔法,但其实原理也很简单〜
先看看最经典的程序入口程序:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
我们先把pool看成一个普通对象〜很简单,先是alloc,pool的retainCount为1。第三句release,retainCount为0,自动调用它的dealloc方法。它和任何其它普通对象没 任何区别。
魔法在哪里?
在声明pool后,release它之前的这段代码,所有段里的代码(先假设中间没有声明其它的AutoreleasePool实例),凡是调用了autorelase方法的实例,都会把它的retainCount加1,并在此pool实例中添1次此实例要回收的记录以做备案。当此pool实例dealloc时,首先会检查之前备案的所有实例,所有记录在案的实例都会依次调用它的release方法。
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSObject *o = [[NSObject alloc] init]; [o autorelease]; //在pool实例dealloc时,release一次此实例,重要的是并不是在此行去release NSLog(@"o retainCount:%d",[o retainCount]); //此时还可以看到我们的o实例还是可用的,并且retainCount为1 [pool release]; //pool 的 retainCount为0,自动调用其dealloc方法,我们之前备案的小o也将在这里release一次(因为咱们之前仅仅autorelease一次)
真对同一个实例,同一个Pool是可以多次注册备案(autorelease)的。在一些很少的情况化可能会出现这种需求:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSObject *o = [[NSObject alloc] init]; [o retain]; [o autorelease]; [o autorelease]; [pool release];
我们调用了两次A类(retainCount加1的方法),使其retainCount为2,而接下来的两次autorelease方法调用,使其在pool中注册备案了两次。这里的pool将会在回收时调用此实例的两次release方法。使其retainCount降为0,完成回收内存的操作,其实这也是完全按照内存管理规则办事的好处〜
AutoreleasePool是被嵌套的!
池是被嵌套的,嵌套的结果是个栈,同一线程只有当前栈顶pool实例是可用的:
| pool_3 |
| --------- |
| pool_2 |
| --------- |
| pool_1 |
|_______|
其代码如下:
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool3 = [[NSAutoreleasePool alloc] init]; NSObject *o = [[NSObject alloc] init] autorelease]; [pool3 release]; [pool2 release]; [pool1 release];
我们可以看到其栈顶是pool3,o的autorelease是把当前的release放在栈顶的pool实例管理。。。也就是pool3。
在生命周期短,产生大量放在autoreleasePool中管理实例的情况下经常用此方法减少内存使用,达到内存及时回收的目的。
AutoreleasePool还被用在哪里?
在上面的例子里,也可以看到,我们在执行autorelease方法时,并没有时时的进行release操作〜它的release被延时到pool实例的dealloc方法里。这个小细节使我们的Objective-C用起来可以在方法栈中申请堆中的内存,创建实例,并把它放在当前pool中延迟到此方法的调用者释放〜
http://www.cocoachina.com/bbs/read.php?tid-12760.html
发表评论
-
iphone编程之UILabel 用法详解
2012-12-18 14:38 1400这段代码动态的创建了一个UILabel,并且把相关常用的属 ... -
IOS用正则验证手机号
2012-12-14 12:01 17202- (BOOL)validateMobile:(NSStr ... -
UITableView技巧之去除UITableViewCell边框
2012-12-14 10:42 3600有时候想在UITableViewCell中加内容,但又不想要c ... -
MAC MySQL Workbench执行批量更新和删除的时候错误解决
2012-10-25 11:21 3999处理MySQL更新表时ErrorCode:1175.You a ... -
Objective-C编码风格指南
2012-10-17 17:00 1213参考资料: • Apple: Coding Guideline ... -
autorelease对象具体什么时候释放?
2012-09-19 15:21 1038在项目中,会有一个默认的Autorelease pool,程序 ... -
Objective-C内存管理教程和原理剖析
2012-09-10 14:44 896此文涉及的内存管理是针对于继承于NSObject的Clas ... -
IOS开发内存释放小结
2012-09-03 17:34 5362内存释放是iphone开发过程中比较重的地方,所以在开辟内存后 ... -
为什么Android没有iOS那么顺滑
2012-08-29 14:38 901虽然很多Android手机的配 ... -
UITextView关闭键盘
2012-08-29 14:13 142061.如果你程序是有导航条的,可以在导航条上面加多一个Done的 ... -
Mac系统下查看鼠标所在点的RGB值--数码测色计
2012-08-29 14:05 1791苹果电脑的Mac OS X系统自带鼠标所在点颜色RGB值查看工 ... -
UIView你知道多少
2012-08-21 09:49 839曾经有人这么说过,在i ... -
iOS内存管理
2012-08-17 18:19 28341. 内总管理原则(引用计数) IOS的对象都继承于 ... -
IOS 获取当前系统时间的年、月、日、小时、分、秒
2012-08-14 17:33 6613NSCalendar *calendar = [[NSCa ... -
IOS判断是否为数字
2012-08-13 17:59 4900判断是否为整形: - (BOOL)isPureInt:(N ... -
self.用法
2012-08-09 14:55 846MyClass.h @interface MyClass ... -
#import与@class的区别
2012-08-08 17:13 9371.import会包含这个类的所有信息,包括实体变量和方法,而 ... -
iphone图标去掉光晕效果
2012-08-07 16:53 1156图片背景是透明的 如果想去掉光晕效果,就在info.plist ... -
去掉 App Store 内图标上部高亮效果的办法
2012-08-07 16:52 888苹果默认会在 App Store 里的应用图标上半部自 ... -
继承UIView时使用xib文件布局的方法以及关键问题
2012-08-02 18:06 43881. 首先,新建一个类,继承自UIView。 2. 创建一个空 ...
相关推荐
《Objective-C高级编程:iOS与OS X多线程和内存管理》是一本深入探讨Apple平台开发中的关键技术的书籍。本书主要围绕Objective-C语言在iOS和OS X操作系统上的应用,特别是针对多线程和内存管理这两个核心主题进行...
Objective-C语言入门教程&深入浅出,理论实践相结合 Objective-C语言入门教程&深入浅出,理论实践相结合 Objective-C语言入门教程&深入浅出,理论实践相结合 Objective-C语言入门教程&深入浅出,理论实践相结合 ...
Objective-C的内存管理是一种重要的编程技能,它对于创建出色的应用程序至关重要。在深入探讨Objective-C内存管理之前,让我们以日常生活中的比喻来形象说明内存管理的过程:当我们在家中自己做饭时,需要亲自处理...
综上所述,本教程覆盖了Objective-C编程语言的基础知识点,不仅包括语法和结构,还包括与C语言的兼容性、内存管理机制、面向对象编程的核心概念、以及如何在不同操作系统平台上进行开发的介绍。通过这些内容的学习,...
"第八讲 内存管理"是Objective-C开发中非常重要的一个环节,讲解了自动引用计数(ARC)和手动内存管理(MRC)的原理,以及如何避免内存泄漏。 最后,"第九讲 Foundation框架"介绍了苹果的基础框架,它提供了一系列...
Objective-C的内存管理机制与.NET和Java等语言中常见的自动垃圾回收机制不同,它更接近于C语言的手动管理方式,但在此基础上加入了一些自动化手段,使得开发人员能够在一定程度上简化内存管理的工作。 ##### 1. ...
Objective-C语言的许多决策可以在编译和运行时执行。只要有可能,它是动态的。这意味着Objective-C语言不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。Runtime系统是一种用于Objective-C语言的操作系统...
Objective-C 2.0引入了属性声明的概念,这是一种简化属性访问和管理的方式。属性声明使开发者能够轻松地为对象定义属性,并控制这些属性的存取方式。属性还可以指定合成(synthesis)属性,这使得编译器能够自动生成...
7. **ARC(Automatic Reference Counting)**:ARC是Objective-C中的内存管理机制,自动处理对象引用计数,避免了内存泄漏和过早释放的问题。 8. ** Blocks **:Objective-C引入了Blocks,这是一种内联函数或闭包,...
总结来说,在Windows系统下搭建Objective-C开发环境虽然不像在Mac OS X上那样直接便捷,但通过使用GNUstep等工具,我们依然可以实现在Windows系统下的Objective-C开发。希望这份详细的指南能够帮助那些需要或希望在...
Objective-C内存管理是iOS开发中非常重要的一部分。在早期的Objective-C中,内存管理是通过引用计数(Reference Counting)的方式进行的,开发者需要手动对对象的引用进行管理。内存管理的基本原则可以概括为“谁...
C语言是计算机编程的基础,它是Objective-C的重要基石。在学习Objective-C之前,深入理解C语言的知识点至关重要。C语言以其高效、简洁和灵活性被广泛应用于系统编程、嵌入式开发、游戏引擎等领域。本资料主要涵盖了...
- **内存管理**:Objective-C使用ARC(Automatic Reference Counting),而C++使用自己的内存管理规则。在混用时要特别注意内存泄漏问题。 - **命名冲突**:C++的命名空间和Objective-C的类别可能会引起命名冲突,...
5. **内存管理**:Objective-C使用引用计数进行内存管理,书中会详细解释如何正确地持有和释放对象,以避免内存泄漏。 6. **NSObjects和协议**:Objective-C中的NSObject类是所有其他类的基类,书中会讲解它的方法...
### Objective-C内存管理教程和原理剖析 #### 一、前言 Objective-C 是一种面向对象的编程语言,广泛应用于苹果的 macOS 和 iOS 开发中。由于 Objective-C 的内存管理机制与现代高级语言如 Java 或 .Net 的自动垃圾...
希望这个简单的Objective-C语言教程能够为你提供一个入门的起点。Objective-C是一种面向对象的编程语言,广泛应用于Mac OS和iOS开发。通过学习Objective-C的基本语法、类和对象、控制流程和方法等内容,你将能够编写...
《Objective-C 程序设计(第4版)》已经为iOS 5和Xcode4.2中的重大变更做了全面更新,最大的改动是引入了自动引用计数(ARC),并详细说明了如何在Objective-C编程过程中使用ARC提升和简化内存管理。
4. **Foundation框架**:介绍Objective-C开发中最常用的Foundation框架,包括字符串处理、集合类(NSArray, NSDictionary等)、内存管理等基础工具的使用。 5. **Cocoa Touch**:对于iOS开发,会讲解Cocoa Touch...
Objective-C语法的基石是C语言的语法结构,这意味着所有的C语言代码都可以在Objective-C中直接使用。但是,Objective-C在C的基础上新增了消息传递机制,这是它与C语言的一个重要区别。在Objective-C中,方法调用是...
2. **内存管理**:Objective-C 2.0引入了自动引用计数(ARC),大大简化了内存管理。开发者不再需要手动调用`retain`、`release`和`autorelease`,而是由编译器自动处理。 3. **分类与协议**:Objective-C允许对已...