iPhoneMac Objective-C内存管理教程和原理剖析

合集下载

cocoa框架

cocoa框架

我们定义一个住址类型的类:
Address.h
#import <Foundation/Foundation.h>
@interface Address: NSObject{
NSString *city;
NSString *y: (NSString*) c;
[b m: a];
[c m: a];
}
上面的代码就将a 传递给了b、c 两个实例,而a 实例本身又是在main 函数中定义的,因此一共有main 函数、b、c 三个地方引用了a 实例。那么由上面的代码引出了这样的问题:你在alloc 一个对象之后,什么时候dealloc 它呢?回收早了可能导致有些还在引用的地方会报错,不回收自然会导致内存泄漏。
cocoa 框架
(经典推荐) Objective-C 的语法与Cocoa 框架----02 (2011-08-10 11:17)
分类: iphone
14. 内存管理:
JAVA 使用GC 机制自动管理内存的,Objective-C 支持手动管理内存,也支持GC 机制,但是GC 机制对于iOS 设备无效,也就是仅对Mac OS X 电脑有效。这是合理的,因为iPhone、iPod、iPad 等的内存、CPU 肯定要比电脑低很多,你必须谨慎对待内存的使用,而不能肆无忌惮的等着GC 帮你去收拾烂摊子。
防止它会被意外调用而出现空指针异常。
但我认为你这样可能屏蔽了错误,不是一个好办法。
只要实例是alloc、new、copy 出来的,你就需要选择完全手动的管理内存,也就是你要负责release。(谁申请,谁释放)
main 函数
// initWithString 是NSString 的一个使用NSString 字面值初始化的方法。与直接使用下面的C语言字符序列初始化相比,@” ”支持Unicode 字符集。

好程序员特训营学习笔记ios内存问题

好程序员特训营学习笔记ios内存问题

Objective-C提供了三种内存管理方式:manual retain-release(MRR,手动管理),automatic reference counting(ARC,自动引用计数),garbage collection(垃圾回收)。

iOS不支持垃圾回收;ARC作为苹果新提供的技术,苹果推荐开发者使用ARC技术来管理内存;这篇笔记主要讲的是手动管理。

内存管理的目的是:1.不要释放或者覆盖还在使用的内存,这会引起程序崩溃;2.释放不再使用的内存,防止内存泄露。

iOS程序的内存资源是宝贵的。

MRR手动管理内存也是基于引用计数的,只是需要开发者发消息给某块内存(或者说是对象)来改变这块内存的引用计数以实现内存管理(ARC技术则是编译器代替开发者完成相应的工作)。

一块内存如果计数是零,也就是没有使用者(owner),那么objective-C的运行环境会自动回收这块内存。

objective-C的内存管理遵守下面这个简单的策略:注:文档中把引用计数加1的操作称为“拥有”(own,或者take ownership of)某块对象/内存;把引用计数减1的操作称为放弃(relinquish)这块对象/内存。

拥有对象时,你可以放心地读写或者返回对象;当对象被所有人放弃时,objective-C的运行环境会回收这个对象。

1.你拥有你创建的对象也就是说创建的对象(使用alloc,new,copy或者mutalbeCopy等方法)的初始引用计数是1。

2.给对象发送retain消息后,你拥有了这个对象3.当你不需要使用该对象时,发送release或者autorelease消息放弃这个对象4.不要对你不拥有的对象发送“放弃”的消息注:简单的赋值不会拥有某个对象。

比如:...NSString *name = ;...上面这个赋值操作不会拥有这个对象(这仅仅是个指针赋值操作);这和C++语言里的某些基于引用计数的类的行为是有区别的。

Objective菜鸟教程

Objective菜鸟教程

Objective-C 入门教程分类编程技术Objective-C是一种简单的计算机语言,设计为可以支持真正的面向对象编程。

Objective-C 通过提供类定义,方法以及属性的语法,还有其他可以提高类的动态扩展能力的结构等,扩展了标准的ANSI C语言。

类的语法和设计主要是基于Smalltalk,最早的面向对象编程语言之一。

如果你以前使用过其他面向对象编程语言,那么下面的信息可以帮助你学习Objective-C 的基本语法。

许多传统的面向对象概念,例如封装,继承以及多态,在Objective-C中都有所体现。

这里有一些重要的不同,但是这些不同在这文章会表现出来,而且如果你需要还有更多详细的信息存在。

如果你从来没有使用任何编程语言编过程序,那么你至少需要在开始之前,对相关概念进行一些基础的了解。

对象的使用和对象对象架构是iPhone程序设计的基础,理解他们如何交互对创建你的程序非常重要。

想了解面向对象概念的,请参看使用Objective-C进行面向对象编程。

此外,参看Cocoa基础指南可以获得Cocoa中的面向对象设计模式的信息。

Objective-C:C的超集Objective-C是ANSI版本C编程语言的超集,支持C的基本语法。

在C代码中,你定义头文件和源代码文件,从代码实现细节分离公共声明。

Objective-C头文件使用的文件名列在表1中。

表1 Objective-C代码的文件扩展名扩展名内容类型.h 头文件。

头文件包含类,类型,函数和常数的声明。

.m 源代码文件。

这是典型的源代码文件扩展名,可以包含Objective-C和C代码。

.mm 源代码文件。

带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。

仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名。

当你需要在源代码中包含头文件的时候,你可以使用标准的#include编译选项,但是Objective-C提供了更好的方法。

O_C基础知识

O_C基础知识

objective-c基础教程——学习小结提纲:简介与C语言相比要注意的地方objective-c高级特性开发工具介绍(cocoa 工具包的功能,框架,源文件组织;XCode使用介绍)简介:1. objective-c是C语言的一个扩展集,主要由APPLE公司维护,是MAC系统下的主要开发语言。

个人认为,对于用惯了常用的C,JAVA等语言的人来说,objective-c是一中很另类,非主流的语言。

2. 开发Mac的UI 程序来说,使用的是Cocoa 这个框架,cocoa的组成部分有:foundation和application kit框架。

【foundation框架处理用户界面之下的特性,如数据结构和通信机制;application kit框架包含cocoa的高级特性:用户界面元素,打印,颜色,声音管理,applescript等】3. 我通过这本书的学习:基本掌握了Objective C的语法,基本能看懂别人写的代码,自己也能编写代码;熟悉了开发环境XCode的使用;(包括建立项目,调试,运行,代码管理等)与C语言相比要注意的地方:1. 文件介绍:Objective-C 也使用头文件(header files),后缀为 .h, 但使用 .m(即message, 其他面向对象编程语言也叫method),作为源文件的后缀。

在objective-c中使用#import<>,而不使用#include<>,#import可以保证头文件只被包含一次。

2. 与C一致的地方:数据类型,表达式,各种运算符循环:for, while, do while, break, continue分支:if, else, switch3. NSlog()函数:与printf()类似,想控制台输出信息。

但它增加了一些特性,如时间戳等。

【cocoa对起所有的函数,常量和类型名称都添加了NS前缀。

】4. 双引号的前面的@表示这双引号中的字符串应该作为cocoa的NSString元素来处理。

Objective-C 2.0之前需要了解的:关于Obj-C内存管理的规则

Objective-C 2.0之前需要了解的:关于Obj-C内存管理的规则

Objective-C 2.0之前需要了解的:关于Obj-C内存管理的规则/index.php/archives/cocoachina_110.htmlObjective-C 2.0增加了一些新的东西,包括属性和垃圾回收。

那么,我们在学习Objective-C 2.0之前,最好应该先了解,从前是什么样的,为什么Objective-C 2.0要增加这些支持。

这一切都跟Cocoa内存的管理规则有关系,我们知道,Objective-C中所有变量都定义为指针。

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址,如果使用不当,就会出错或者造成内存的泄露。

要了解这些,就需要看看其内存管理的规则到底是什么样的。

这篇文章也应该做为苹果开发工具中提供的性能调试工具Instruments使用前必读知识进行阅读。

Cocoa China将在稍后提供Instruments工具的使用方法,以及Objective-C 2.0的详细介绍。

要知道,如果你使用Objective-C 2.0,那么本文描述的大部分工作你都不需要自己去处理了。

但是这并不意味着你可以不了解它,相反,只有你对内存管理规则更加了解,你才能更好地使用Objective-C 2.0带来的便利。

本文原文作者是Mmalcolm Crawford,原文地址这篇文章翻译起来比较晦涩,希望您能看得懂。

当Cocoa新手在进行内存管理时,他们看上去总是把事情变得更为复杂。

遵循几个简单的规则就可以把生活变得更简单。

而不遵循这些规则,他们几乎一定会造成诸如内存泄露或者将消息发送给释放掉的对象而出现的的运行错误。

Cocoa不使用垃圾回收(当然,Objective-C 2.0之后开始就使用了),你必须通过计算reference的数量进行自己的内存管理,使用-retain, -release和-autorelease。

方法描述-retain将一个对象的reference数量增加1。

iPhone_Mac Objective-C内存管理教程和原理剖析

iPhone_Mac Objective-C内存管理教程和原理剖析

前言初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃。

我在这里总结了自己对objective-C内存管理机制的研究成果和经验,写了这么一个由浅入深的教程。

希望对大家有所帮助,也欢迎大家一起探讨。

此文涉及的内存管理是针对于继承于NSObject的Class。

一、基本原理Objective-C的内存管理机制与.Net/Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍微加了一些自动方法。

1 Objective-C的对象生成于堆之上,生成之后,需要一个指针来指向它。

ClassA *obj1 = [[ClassA alloc] init];2 Objective-C的对象在使用完成之后不会自动销毁,需要执行dealloc来释放空间(销毁),否则内存泄露。

[obj1 dealloc];这带来了一个问题。

下面代码中obj2是否需要调用dealloc?ClassA *obj1 = [[ClassA alloc] init];ClassA *obj2 = obj1;[obj1 hello]; //输出hello[obj1 dealloc];[obj2 hello]; //能够执行这一行和下一行吗?[obj2 dealloc];不能,因为obj1和obj2只是指针,它们指向同一个对象,[obj1 dealloc]已经销毁这个对象了,不能再调用[obj2 hello]和[obj2 dealloc]。

obj2实际上是个无效指针。

如何避免无效指针?请看下一条。

3 Objective-C采用了引用计数(ref count或者retain count)。

对象的内部保存一个数字,表示被引用的次数。

例如,某个对象被两个指针所指向(引用)那么它的retain count为2。

需要销毁对象的时候,不直接调用dealloc,而是调用release。

(IOS)Objective-C最受欢迎入门教程

(IOS)Objective-C最受欢迎入门教程

你不用考虑它什么时候开始工作,
工作。你只需要明白, 我申请了一段内存空间, 当我不再使用从而这段内存成为垃圾的时候, 我就彻底的把它忘记掉, 反正那个高人会帮我收拾垃圾。 遗憾的是, 那个高人需要消耗一定 不 支 持 这个 功 能 。 所 以 ”内部机制感兴 ”不大适合适初学
2.1 所示。
图 2-1 ,新建项目 注意也许有人会问,你不是要讲解 下面的“ Application ”呢? Objective-C 的语法的讲解,为了使得讲解 iPhone 的开发,那么为什么不选择“ iPhoneOS ”
是这样的,在这个系列当中,笔者主要侧重于
简单易懂, 清除掉所有和要讲解的内容无关的东西, 行。 第三步, Xcode 会提问你项目的名字,在“ 选择“ Save ”。如图 2-2 所示
Xcode 的话,为了可以熟悉开发环境,强烈建议按照笔者的步骤一步一步的
个对话框。这个对话框和我们的主题没有关系,我们可以把它关掉。 第二步,选择屏幕上部菜单的“ File->NewProject ” , 出现了一个让你选择项目种类的 ” , 然 后在 右 边 选 择
对 话 框 。 你 需 要 在 对 话 框 的 左 边 选 择 “ CommandLineUtility “ FoundationTool ” , 然后选择“ Choose... ”按钮。如图
Objective-C
的基本使用方法,为了避免过多的新鲜东西给同
学们造成阅读上的困难,所以命令行就已经足够了。 说到这里, 笔者需要澄清一点, 其实 MACOS 的 Cocoa 和 iPhone 的 Cocoa 是不一样 的,可以说,其中 2.3 , main 函数 有过 C/C++ 或者 java 经验的同学们对第 序的入口都是 3 行代码应该很熟悉了, 是的大家都一样主程 main 是完全一样的,和 java 语言 iPhone 是 MACOS 的一个子集。

学习Objective-C入门教程(全)

学习Objective-C入门教程(全)

学习Objective-C入门教程1,前言相信iPhone不久就要在国内发布了,和我们在国内可以通过正规渠道买得到的iPodTouch一样,iPhone也是一个激动人心的产品。

iPhone发布的同时,基于iPhone的程序也像雨后春笋一样在iTunes里面冒出来。

你将来也许会考虑买一个iPhone,体验一下苹果的富有创意的种种应用;你也许会考虑向iTunes的社区的全世界的人们展示一下你非凡的创意,当然也可以通过你的创意得到一些意想不到的收益。

OK,你也许迫不及待的准备开发了。

但是先等一下,让我们回忆一下最初的电影是怎么拍摄的。

这个很重要,因为和iPhone的开发比较类似。

在最初因为器材比较原始,所以拍摄电影需要很高的技术,那个时候的电影的导演基本上是可以熟练操作摄影器材的人。

随着器材的完善,使用也简单起来。

于是器材的使用不是决定一个电影的质量的唯一的因素,取而代之的是故事或者说电影的创意。

iPhone的开发也是这样。

当然从入门到掌握的过程来说任何事情都是开始比较难,随着掌握的程度的加深,你将会觉得开发iPhone应用程序是一件简单而且轻松的事情,到了那个时候,你的主要的制胜武器就不是开发技术,而是你的创意了。

对于你来说,我在这里写的东西都是有关“摄影器材”也就是介绍如何使用iPhone的平台来开发应用程序。

iPhone的开发语言是Objective-C。

Objective-C是进行iPhone开发的主要语言,掌握了Objective-C的基本语法以及数据结构之后,你需要熟悉一下iPhone的SDK。

笔者很难做到在一篇文章里面把所有的东西都介绍清楚,所以笔者打算分成两个主题,一个是Objective-C,一个是iPhone开发。

本系列将侧重于Objective-C。

当然,任何一种开发语言都无法脱离于运行环境,Objective-C也不例外。

所以在本系列当中也会穿插的介绍一些SDK里面的一些特性,主要是数据结构方面,比如说NSString,NSArray等等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

iPhone/Mac Objective-C内存管理教程和原理剖析Vince Yuan (vince.yuan@) 前言初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃。

我在这里总结了自己对objective-C内存管理机制的研究成果和经验,写了这么一个由浅入深的教程。

希望对大家有所帮助,也欢迎大家一起探讨。

此文涉及的内存管理是针对于继承于NSObject的Class。

一基本原理Objective-C的内存管理机制与.Net/Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍微加了一些自动方法。

1、Objective-C的对象生成于堆之上,生成之后,需要一个指针来指向它。

ClassA *obj1 = [[ClassA alloc] init];2、Objective-C的对象在使用完成之后不会自动销毁。

需要执行dealloc来释放空间(销毁),否则内存泄露。

[obj1 dealloc];这带来了一个问题。

下面代码中obj2是否需要调用dealloc?ClassA *obj1 = [[ClassA alloc] init];ClassA *obj2 = obj1;[obj1 hello]; //输出hello[obj1 dealloc];[obj2 hello]; //能够执行这一行和下一行吗?[obj2 dealloc];不能,因为obj1和obj2只是指针,它们指向同一个对象,[obj1 dealloc]已经销毁这个对象了,不能再调用[obj2 hello]和[obj2 dealloc]。

obj2实际上是个无效指针。

如何避免无效指针?请看下一条。

3、Objective-C采用了引用计数(ref count或者retain count)。

对象的内部保存一个数字,表示被引用的次数。

例如,某个对象被两个指针所指向(引用)那么它的retain count为2。

需要销毁对象的时候,不直接调用dealloc,而是调用release。

release会让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。

ClassA *obj1 = [[ClassA alloc] init];//对象生成时,retain count = 1[obj1 release];//release使retain count减1,retain count = 0,dealloc自动被调用,对象被销毁我们回头看看刚刚那个无效指针的问题,把dealloc改成release解决了吗?ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1ClassA *obj2 = obj1; //retain count = 1[obj1 hello]; //输出hello[obj1 release]; //retain count = 0,对象被销毁[obj2 hello];[obj2 release];[obj1 release]之后,obj2依然是个无效指针。

问题依然没有解决。

解决方法见下一条。

4、Objective-C指针赋值时,retain count不会自动增加,需要手动retain。

ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1ClassA *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,不会被销毁,内存泄露。

这样的确不会内存泄露,但似乎有点麻烦,有没有简单点的方法?见下一条。

5、Objective-C中引入了autorelease pool(自动释放对象池),在遵守一些规则的情况下,可以自动释放对象。

(autorelease pool依然不是.Net/Java那种全自动的垃圾回收机制)5.1 新生成的对象,只要调用autorelease就行了,无需再调用release!ClassA *obj1 = [[[ClassA alloc] init] autorelease];//retain count = 1 但无需调用release5.2 对于存在指针赋值的情况,代码与前面类似。

ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1 ClassA *obj2 = obj1; //retain count = 1[obj2 retain]; //retain count = 2[obj1 hello]; //输出hello//对于obj1,无需调用(实际上不能调用)release[obj2 hello]; //输出hello[obj2 release]; //retain count = 2-1 = 1细心的读者肯定能发现这个对象没有被销毁,何时销毁呢?谁去销毁它?请看下一条。

6、autorelease pool原理剖析。

6.1 autorelease pool不是天生的,需要手动创立。

只不过在新建一个iphone项目时,xcode 会自动帮你写好。

autorelease pool的真名是NSAutoreleasePool。

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];6.2 NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease 的所有对象。

如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。

ClassA *obj1 = [[[ClassA alloc] init] autorelease];//retain count = 1,把此对象加入autorelease pool中6.3 NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。

如果此时数组中成员的retain count为1,那么release之后,retain count为0,对象正式被销毁。

如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,此对象依然没有被销毁,内存泄露。

6.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销毁时才被释放,你需要考虑下一条。

7、Objective-C程序中可以嵌套创建多个autorelease pool。

在需要大量创建局部变量的时候,可以创建内嵌的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运行时通过监控工具可以发现使用占用内存的变化极小。

二口诀与范式1、口诀。

1.1 谁创建,谁释放(类似于“谁污染,谁治理”)。

如果你通过alloc、new或copy来创建一个对象,那么你必须调用release或autorelease。

换句话说,不是你创建的,就不用你去释放。

例如,你在一个函数中alloc生成了一个对象,且这个对象只在这个函数中被使用,那么你必须在这个函数中调用release或autorelease。

如果你在一个class的某个方法中alloc 一个成员对象,且没有调用autorelease,那么你需要在这个类的dealloc方法中调用release;如果调用了autorelease,那么在dealloc方法中什么都不需要做。

1.2 除了alloc、new或copy之外的方法创建的对象都被声明了autorelease。

1.3 谁retain,谁release。

只要你调用了retain,无论这个对象是如何生成的,你都要调用release。

有时候你的代码中明明没有retain,可是系统会在默认实现中加入retain。

相关文档
最新文档