﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-小秋的家-文章分类-object-c</title><link>http://www.blogjava.net/mycolby/category/47485.html</link><description>home</description><language>zh-cn</language><lastBuildDate>Fri, 31 Dec 2010 11:15:26 GMT</lastBuildDate><pubDate>Fri, 31 Dec 2010 11:15:26 GMT</pubDate><ttl>60</ttl><item><title>object c 内存管理(转载)</title><link>http://www.blogjava.net/mycolby/articles/341995.html</link><dc:creator>棋剑小秋</dc:creator><author>棋剑小秋</author><pubDate>Thu, 30 Dec 2010 07:47:00 GMT</pubDate><guid>http://www.blogjava.net/mycolby/articles/341995.html</guid><wfw:comment>http://www.blogjava.net/mycolby/comments/341995.html</wfw:comment><comments>http://www.blogjava.net/mycolby/articles/341995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mycolby/comments/commentRss/341995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mycolby/services/trackbacks/341995.html</trackback:ping><description><![CDATA[<h3><a href="http://kakashi.javaeye.com/blog/465064"><br />
</a></h3>
<div class="blog_content">
<p> 看了下官方文档的关于object c 的内存管理,总结下:</p>
<div> 在iphone中object c 中的内存管理是通过计数器来管理的,每个对象内部都有一个计数器.新建一个对象,或者这个对象被其他对象引用,多会使计数器加1.<span><span style="font-size: x-small;">Retain 增加计数器值</span></span><span style="font-family: Times,sans-serif; font-size: small;"><span style="font-size: x-small;">release 减少计数器值.当计数器为0时对象就dealloc自己.</span></span>
</div>
<div>在object c中你生成的一个对象那么你就有责任去释放它，内存管理的一般规则：</div>
<h2 class="jump section2"><span style="font-size: medium;">
<ul class="ul">
    <li class="li">
    <p><span style="font-size: x-small;">You own any object you create by allocating memory for it or copying it.</span></p>
    <p><span style="font-size: x-small;">Related methods:</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/clm/NSObject/alloc" target="_blank"><span style="font-size: x-small;">alloc</span></a><span style="font-size: x-small;">,</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/clm/NSObject/allocWithZone:" target="_blank"><span style="font-size: x-small;">allocWithZone:</span></a><span style="font-size: x-small;">,</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/copy" target="_blank"><span style="font-size: x-small;">copy</span></a><span style="font-size: x-small;">,</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSCopying/copyWithZone:" target="_blank"><span style="font-size: x-small;">copyWithZone:</span></a><span style="font-size: x-small;">,</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/mutableCopy" target="_blank"><span style="font-size: x-small;">mutableCopy</span></a><span style="font-size: x-small;">,</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSMutableCopying_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSMutableCopying/mutableCopyWithZone:" target="_blank"><span style="font-size: x-small;">mutableCopyWithZone:</span></a></p>
    </li>
    <li class="li">
    <p><span style="font-size: x-small;">If you are not the creator of an
    object, but want to ensure it stays in memory for you to use, you can
    express an ownership interest in it.</span></p>
    <p><span style="font-size: x-small;">Related method:</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/retain" target="_blank"><span style="font-size: x-small;">retain</span></a></p>
    </li>
    <li class="li">
    <p><span style="font-size: x-small;">If you own an object, either by
    creating it or expressing an ownership interest, you are responsible for
    releasing it when you no longer need it.</span></p>
    <p><span style="font-size: x-small;">Related methods:</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/release" target="_blank"><span style="font-size: x-small;">release</span></a><span style="font-size: x-small;">,</span><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/autorelease" target="_blank"><span style="font-size: x-small;">autorelease</span></a></p>
    </li>
    <li class="li">
    <p><span style="font-size: x-small;">Conversely, if you are not the creator of an object and have not expressed an ownership interest, you must</span><em><span style="font-size: x-small;">not</span></em><span style="font-size: x-small;">release it.</span></p>
    <p><span style="font-size: xx-small;"><br />
    </span></p>
    </li>
</ul>
</span></h2>
<p>
</p>
<div>考虑下面这个例子：</div>
<div><span style="font-family: 'Courier New';"> Thingamajig *thingamajig = [[Thingamajig alloc] init];</span></div>
<div><span style="font-family: 'Courier New';"> NSArray *sprockets = [thingamajig sprockets];</span></div>
<div><span style="font-family: 'Courier New';"> [thingamajig release];</span></div>
<div><span style="font-family: 'Courier New';">
<div><span style="font-family: 'Courier New';">thingamajig 需要release，因为很显然这里我们是<span style="font-family: 'Courier New';">thingamajig</span>的owner。（第一条规则）</span></div>
<div>那么<span style="font-family: 'Courier New';">sprockets</span>为什么不需要<span style="font-family: 'Courier New';">release</span>呢。<br />
首先我们不是<span style="font-family: 'Courier New';">sprockets</span>的 creater.<span style="font-family: 'Courier New';">（第一条规则）,我们也没有expressing an ownership interest，因为我们没有</span><br />
<span style="font-size: x-small;">retain它，（第二条规则） 所以我们不负责release它。</span><br />
具体来看<span style="font-family: 'Courier New';">thingamajig</span>的<span style="font-family: 'Courier New';">sprockets</span>方法的实现：</div>
<div> <span style="font-family: 'Courier New';">(NSArray *)sprockets {</span>
</div>
<div>
<span style="font-family: 'Courier New';">NSArray *array;</span><br />
<span style="font-family: 'Courier New';">array = [[NSArray alloc] initWithObjects:mainSprocket,<span style="font-family: 'Courier New';">auxiliarySprocket, nil];</span></span><br />
<span style="font-family: 'Courier New';">return [array autorelease];</span><br />
<span style="font-family: 'Courier New';">}</span>
</div>
<div><span style="font-family: 'Courier New';">可见分配的内存在方法里就已经用<span style="font-family: 'Courier New';">autorelease</span>释放了，只不过是稍后释放。参见autorelease pool。</span></div>
<div><span style="font-family: 'Courier New';">
<div><strong>这里有个很重要的原则：</strong></div>
<div>
<strong> Because</strong><em><strong>the class</strong></em><strong>creates the new object,</strong><em><strong>it</strong></em><strong>is responsible for disposing of the new object.<br />
</strong>
</div>
<div><strong>这个对象在哪里生成的，就应该在哪里释放。</strong></div>
<div><strong>
<div><span style="font-weight: normal;">所以你看到很多类有以自己类名为方法的构造函数，你调用的时候就不需要release.因为在这个构造函数中已经做</span></div>
<div>
<span style="font-weight: normal;">过</span><span style="font-family: 'Courier New';"><span style="font-weight: normal;">autorelease</span></span><span style="font-weight: normal;">了。</span>
</div>
<div><span style="font-weight: normal;">你没有alloc这个对象就不负责release它</span></div>
<div><span style="font-weight: normal;">
<div>现在来看规则2，有些时候我们在自己的类里要引用其他的对象，如把这个其他的对象变成自己的成员变量。</div>
<div>那么就有一个问题，这个被引用的对象是否被release不被你控制，一旦它被release，你自己的程序就会出问题</div>
<div>这时候我们就需要retain这个对象。表示你这个类也拥有这个对象，只有你自己的类release后，被引用的对象才有可能被release</div>
<div>一般的set 方法：</div>
<div>@interface Counter : NSObject {</div>
<div>
<span style="font-family: 'Courier New';"><span style="font-family: 'Courier New';">NSNumber *count;</span></span><br />
<span style="font-family: 'Courier New';">}</span>
</div>
<div><span style="font-family: 'Courier New';">- (void)setCount:(NSNumber *)newCount {</span></div>
<div>
<span style="font-family: 'Courier New';">[newCount retain];</span><br />
<span style="font-family: 'Courier New';">[count release];</span><br />
<span style="font-family: 'Courier New';">count = newCount;</span>
</div>
<div><span style="font-family: 'Courier New';">}</span></div>
<div><span style="font-family: 'Courier New';">
<div>在set中我们对传进来的对象进行了retain. 为什么要先<span style="font-family: 'Courier New';">retain</span>后<span style="font-family: 'Courier New';">release</span>，因为如果<span style="font-family: 'Courier New';">newCount</span>和<span style="font-family: 'Courier New';">count</span>是同一个对象</div>
<div>先release的话会导致这个对象delloc.</div>
</span></div>
</span></div>
</strong></div>
</span></div>
</span></div>
</div>
<img src ="http://www.blogjava.net/mycolby/aggbug/341995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mycolby/" target="_blank">棋剑小秋</a> 2010-12-30 15:47 <a href="http://www.blogjava.net/mycolby/articles/341995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>