- 浏览: 161545 次
- 性别:
- 来自: 大连
最新评论
-
xueyw:
http://www.devdiv.com/forum-iph ...
iPhone开发网站、论坛、博客 -
Meggie_love:
受教了
游戏算法整理 算法七 无限大地图的实现 -
xueyw:
http://www.devdiv.net/bbs/forum ...
iPhone开发网站、论坛、博客 -
junlas:
APE 物理引擎与 Box2D 物理引擎对比 -
ha397666:
5、扩展的点已经被扩展过了。当扩展节点的时候,每个节点都是向四 ...
游戏算法整理 算法六:关于SLG中人物可到达范围计算的想法
First off, it’s worthing clarifying that much of what is covered here is as much Cocoa as it is Objective-C. However, since the two are quite closely tied when it comes to developing Mac/iPhone applications, I’ve decided to keep with the Objective-C theme as it relates to the title of this and subsequent posts.
This post will review some of the nuances of memory management. I won’t go into all the details of memory management (see Objective-C Programming Guide , Cocoa Fundamentals and Memory Management Programming Guide for Cocoa ), rather, I’ll point out some of the more subtle concepts to keep in mind as you begin to work with objects.
Object Ownership
Rule #1 – If you create an object using alloc, new or a variant of copy (e.g. mutableCopy), you need to free (release or autorelease) that object. This also applies if you send a retain message to an object.
Rule #2 – If you didn’t create an object directly, don’t attempt to release the memory for the object.
For instance, here is an object that I “own” given that I’ve called ‘alloc’ to create the object. It’s up to me to release the memory for this object:
1 2 3 4 5 |
TestClass *ptr = [[TestClass alloc] init]; ... [ptr release]; |
Let’s look at two examples where we are not responsible for managing the memory associated with an object. First, when using a factory (aka convenience) methods of a class. For instance:
1 2 3 |
NSString *str; str = [NSString stringWithFormat:@"Some string here..."]; NSLog(str); |
The second example, is if you call an accessor method that returns an object. Assume that the object TestClass below has a getter method that returns a pointer to an instance variable named firstName that is an NSString.
1 2 3 |
NSString *str; // No need to release this object str = [TestClass firstName]; |
This makes sense if you think about it. The getter simple returns a reference (pointer) to an existing object. Now, if you want to retain (express an interest in the object to keep it around) then you would need to use ‘retain’ to bump the reference count. However, if we simply want a pointer to the object as shown here, we don’t have responsibility to release the object.
Initializing Objects
The order of things happening when initializing an object is of great relevance. For example, look at this block of code:
1 2 3 4 5 6 |
TestClass *ptr = [TestClass alloc]; [ptr init] // Do something with the object if (ptr) ... |
Seems harmless enough, right? Allocate an object and send a message to initialize the object. Here’s the problem, if the init method returns nil (which all good initializers do upon failure to properly initialize an object), the code on line 5 would pass the test (that is, ptr would not be nil).
Now compare that with this approach:
1 2 3 4 5 |
TestClass *ptr = [[TestClass alloc] init]; // Do something with the object if (ptr) ... |
In the code above, assuming the init method returns nil upon failure, ptr will be set to nil, and the code on line 4 would not pass the test. Much better.
So, the lesson here is twofold: always return nil from an initializer method when the method fails to properly initialize the object. Second, it’s a good practice to combine a call to alloc and init into one step. We’ll talk more about initializers in a separate post.
Releasing Objects
Let’s talk about the other end, releasing objects. Have a look at the implementation for a simple class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#import "TestClass.h" // ================================ // = Implementation for TestClass = // ================================ @implementation TestClass -(NSString *) str { return str; } -(void) setStr:(NSString *)input { [input retain]; [str release]; str = input; } -(void) dealloc { [str release]; [super dealloc]; } @end |
Look at the code below that creates an instance of the TestClass, calls the setter method to initialize the ’str’ instance variable, and releases the memory for the ‘ptr’ object.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#import "TestClass.h" int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; TestClass *ptr = [[TestClass alloc] init]; [ptr setStr:@"Fubar"]; [ptr release]; [pool drain]; return 0; } |
The dealloc method in TestClass releases the memory for the ’str’ instance variable, and it seems all is well. However, if at some point, somewhere inside the class implementation an attempt was made to check if the ’str’ instance variable is nil (prior to doing some operation) for example:
1 2 3 4 |
if (str) do something... else do something else... |
the if statement would pass and the code on line 2 would be run. Not a good thing.
An alternative is to replace the call to release with a call to the setter method and pass in nil . Look at the dealloc method below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-(void) setStr:(NSString *)input { [input retain]; [str release]; str = input; } ... -(void) dealloc { [self setStr:nil]; [super dealloc]; } |
The reason this works is that you can send a message to a nil object without raising an exception. If you follow the trail you’ll see inside the setStr method that the variable ‘input’ (which is nil) is sent a message to retain . This is effectively ignored, as the object is nil . The next line releases the string ’str’. The last line sets ’str’ to the value of the input parameter (which is nil ). This prevents the problem in the previous example where ’str’ still had a reference to a location in memory (even though the memory had been released).
As I was getting familiar with this, I wrote a short example in Xcode. Here is the test block for the dealloc method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
-(void) dealloc { NSLog(@"Address of 'str' before release is: %ld", str); // After this, 'str' still points to a memory location [str release]; // After this, 'str' will be nil (** This is the preferred approach **) //[self setStr:nil]; NSLog(@"Address of 'str' is after release is: %ld", str); // Notice the result of this based on how the instance var 'str' is released (above) if (str != nil) printf("'str' still points to a memory location (after being released)!"); else printf("'str' now points to nil."); [super dealloc]; } |
Notice in this case that line 6 uses release. See the output below:
Now, if you comment out line 6 and remove the comment from line 9, you’ll get the following output. Notice how the reference to ’str’ after is 0 (nil).
You can download the Xcode project here if you’d like to take a closer look at the complete example. Hopefully this information will save you some time trying to track down an elusive memory leak.
发表评论
-
UIPickerView – spinning multiple components
2010-08-24 16:24 1614I found an interesting issues w ... -
UITableView效果收集
2010-07-10 12:28 2904某些打不开需翻()墙 Customizing the bac ... -
日期处理
2010-03-17 22:58 1176NSDateFormatter *dateFor ... -
uninstall xcode
2010-02-08 02:35 1730How to uninstall Xcode and ... -
从一个url中获得文本信息(转)
2010-01-21 11:37 1384有时候你可能需要从一个url中获取一个文本文件中的信息。 下面 ... -
将图片保存在iPhone的相册中(转)
2010-01-21 11:28 2924有时候你的应用需要将应用中的图片保存到用户iPhone或者iT ... -
一些遊戲製作有關的博客(转)
2010-01-20 14:57 1170站長在收集站內朋友的博客,然後把它們列出來方便大家看,這的確是 ... -
Beautiful Snowflakes
2010-01-14 18:51 1460It is a application that displa ... -
Layer Programming with Quartz Core
2010-01-08 14:11 3519《转载》 2009/6/25 ... -
如何移除Three20中private API
2010-01-07 22:04 1831Three20 是一个非常有 ... -
iphone下Three20库(From Facebook)的设置使用方法
2010-01-07 22:03 4025Three20是一个编译的静态类库 ,在Xcode中的项目实 ... -
Opera Masks
2010-01-07 01:13 1682It is a application that introd ... -
Java读取星际译王(StarDict)词库
2010-01-06 18:08 2620下面的文件是StarDict的词库格式说明文件: Form ... -
iPhone Coding Tutorial – Creating an Online Leaderboard For Your Games4
2010-01-06 11:06 1520Submitting High Scores To The ... -
iPhone Coding Tutorial – Creating an Online Leaderboard For Your Games3
2010-01-06 11:02 1066Displaying The Scores Table ... -
iPhone Coding Tutorial – Creating an Online Leaderboard For Your Games2
2010-01-06 11:01 731Inserting Scores Into The Dat ... -
iPhone Coding Tutorial – Creating an Online Leaderboard For Your Games1
2010-01-06 10:59 1087As you may have seen, there a ... -
iPhone Coding Tutorial – Inserting A UITextField In A UIAlertView
2010-01-06 10:44 1607This will be a simple tutorial ... -
iPhone Coding Tutorial – In Application Emailing
2010-01-06 10:36 1201A lot of applications you see ... -
Objective-C内存管理总结〜CC专版
2009-12-28 11:09 3011之前写过类似的文章,这篇以做总结,希望能帮助刚上船的兄弟。^_ ...
相关推荐
memory management 动态内存分配 FIFO算法
《Pro .NET Memory Management》这本书由Konrad Kokosa撰写,旨在帮助开发者更好地理解.NET内存管理的内部机制,从而提高代码质量、性能和可扩展性。 #### 二、.NET内存管理概述 .NET内存管理主要涉及两个方面:...
在“Virtual memory management ppt”中,主要探讨了虚拟内存管理的多个关键概念和策略。 11.1 引言:这部分介绍了虚拟内存管理的基本原理,包括替换策略和获取策略。替换策略是当内存满时,系统用来选择哪些页面...
aarch64 Linux Kernel Memory Management, aarch64 Linux Kernel Memory Management, aarch64 Linux Kernel Memory Management
Goals of memory management To provide a convenient abstraction for programming To allocate scarce memory resources among competing processes to maximize performance with minimal overhead
本资源“Memory Management: Algorithms and Implementation in C_C++”聚焦于这一主题,旨在深入探讨如何有效地管理和分配内存,以及在C和C++中实现这些算法。 内存管理主要涉及以下几个关键知识点: 1. **动态...
C_C++ 内存管理算法和实现 Memory Management Algorithms and Implementation in C_C++ C_C++ 内存管理算法和实现 Memory Management Algorithms and Implementation in C_C++ C_C++ 内存管理算法和实现 ...
Pro Multithreading and Memory Management for iOS and OS X with ARC, Grand Central Dispatch epub
"Memory Management Simulator" 是一个模拟器,用于帮助理解并可视化内存管理的过程。这个模拟器利用了Java Swing库来构建用户界面,使得用户能够交互地探索内存分配和回收的机制。 在Java中,内存分为堆(Heap)和...
sdk2003 win32 Memory Management sdk2003 win32 Memory Management
《Memory Management in the Java HotSpot™ Virtual Machine》一文深入探讨了Java HotSpot虚拟机中的内存管理机制,这是Java性能优化的关键领域。HotSpot虚拟机是Oracle JDK和JRE的一部分,以其高性能和优化能力而...
MIT JOS Lab2: Memory Management,上海交通大学最新版本的JOS Lab2完整版代码,80分测试满分 详细解析地址:https://blog.csdn.net/qq_32473685/article/details/99625128
Objective-C Memory Management Essentials will familiarize you with the basic principles of Objective-C memory management, to create robust and effective iOS applications. You will begin with a basic ...
C/C++实现的内存管理算法教材,CHM格式
this book will help you become aware of memory management and how to implement this correctly and effectively while being aware of the benefits at the same time. This tutorial-based book will actively...
### C++内存管理创新:GC Allocator #### 引言 在C++编程中,内存管理一直是一个关键且复杂的任务。大多数C++程序员不得不手动管理内存,包括分配和释放内存资源,这不仅耗时而且容易出错。随着软件工程的发展,...
本资料"Effective Memory Management"深入探讨了内存管理的核心概念、策略和技术。 首先,内存管理的基本概念包括静态内存分配与动态内存分配。静态内存分配通常在编译时完成,如栈内存,其大小和生命周期在编译时...
### 内存管理:算法与C/C++中的实现 #### 内容概览 《内存管理:算法与C/C++中的实现》是一本深入探讨内存管理机制、策略及其在C/C++编程语言中具体实现的专业书籍。作者Bill Blunden通过本书系统地介绍了内存管理...
Oracle发展这么多年,提供了多种的内存管理方式,从最早SGA、PGA手工管理,到9I版本出现的PGA的自动管理,到10G版本出现的SGA自动管理(ASMM),再到11G版本出现的memory自动管理(AMM),Oracle基本是在朝着智能化、...