<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iPhoneGeek 爱疯极客 &#187; 基础</title>
	<atom:link href="http://www.iphone-geek.cn/category/%e7%bc%96%e7%a8%8b/%e5%9f%ba%e7%a1%80/feed" rel="self" type="application/rss+xml" />
	<link>http://www.iphone-geek.cn</link>
	<description>iPhone 新闻，编程，技巧与提示，代码，教程</description>
	<lastBuildDate>Sun, 25 Jul 2010 13:49:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>iPhone用Expat XML解析器</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%94%a8expat-xml%e8%a7%a3%e6%9e%90%e5%99%a8</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%94%a8expat-xml%e8%a7%a3%e6%9e%90%e5%99%a8#comments</comments>
		<pubDate>Fri, 23 Jul 2010 10:29:09 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[开源项目]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=985</guid>
		<description><![CDATA[xml的解析运用的十分广泛，我以前也介绍过使用ticpp（tinyxml的c++版本）进行简单的xml解析，见跨平台代码分享之三–xml解析器，它是采用DOM进行解析。iPhone SDK中自带的NSXMLParsers也可进行xml解析，但是对于解析web server下载的大型文件时效率不够高，有一个第三方的objective  c expat wrapper 采用expat（SAX方式）进行解析，效率非常高。据有人测试，其效率相对于NSXMLParsers约提高了70-80%。

下面是其下载地址。


]]></description>
			<content:encoded><![CDATA[<p>xml的解析运用的十分广泛，我以前也介绍过使用ticpp（tinyxml的c++版本）进行简单的xml解析，见<a title="跨平台代码分享之三–xml解析器" href="编程/跨平台代码分享之三-–-xml解析器">跨平台代码分享之三–xml解析器</a>，它是采用DOM进行解析。iPhone SDK中自带的NSXMLParsers也可进行xml解析，但是对于解析web server下载的大型文件时效率不够高，有一个第三方的<a onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.robbiehanson.com/expat.html');" href="http://www.robbiehanson.com/expat.html">objective  c expat wrapper</a> 采用expat（SAX方式）进行解析，效率非常高。据有人测试，其效率相对于NSXMLParsers约提高了70-80%。</p>
<p><br class="spacer_" /></p>
<p>下面是其<a title="NSXMLParsers" href="http://github.com/zootreeves/iPhoneExpat">下载地址</a>。</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%94%a8expat-xml%e8%a7%a3%e6%9e%90%e5%99%a8/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>调试教程 – 使用UIRecorder Instrument将测试自动化</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b0%83%e8%af%95%e6%95%99%e7%a8%8b-%e2%80%93-%e4%bd%bf%e7%94%a8uirecorder-instrument%e5%b0%86%e6%b5%8b%e8%af%95%e8%87%aa%e5%8a%a8%e5%8c%96</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b0%83%e8%af%95%e6%95%99%e7%a8%8b-%e2%80%93-%e4%bd%bf%e7%94%a8uirecorder-instrument%e5%b0%86%e6%b5%8b%e8%af%95%e8%87%aa%e5%8a%a8%e5%8c%96#comments</comments>
		<pubDate>Mon, 19 Jul 2010 01:52:31 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[调试]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=970</guid>
		<description><![CDATA[（注：这是我以前收集的一篇文章，找不到出处了，稍作修改在此发布）

如果你发现程序的bug，但每次进行测试都需要许多步骤才能重现问题，那么本教程适合你。通常，测试和调试是非常繁琐的事情，iPhone程序的开发尤其如此。

比如说，你有个程序需要经过5个步骤才能到达另一个view。如果你有一个bug发生在这个需要5步之多的view上，通常情况下调试的步骤如下：

运行程序
触击 view 1
触击view 2
触击 view 3
触击 view 4
触击 view 5
(程序崩溃)
修改代码
重复以上步骤


如你所见，这是多么痛苦的事情啊。 Kendall Gelner 在 360iDev 上有关使用Instruments 和 XCode进行调试的若干提示的演讲中，对我而言最为有用的就是将测试自动化。我演示一下应该怎么做:
1. 打开希望测试/调试的程序
2. 在模拟器中运行
3. 打开Instrument – 位于 /Developer/Applications/Instruments
 
 



 
4. 选择 UIRecorder 并按Choose - 你将看到下面窗口


 
5.  然后需要将此工具与iPhone模拟器进程链接。按下下拉菜单选择 Default Target -&#62; Attach to Process -&#62; iPhone Simulator.


6. 再按下 Drive &#38; Record 并在模拟器中完成测试所需的所有步骤。至此，UI Recorder记录下了你的一举一动。完成时，按下Stop按钮。 注意： 在完成记录后请不要移动模拟器，因为这有可能会使弄乱整个处理过程。
7. 修改你的代码…
8. 按下 Drive &#38; Record [...]]]></description>
			<content:encoded><![CDATA[<p>（注：这是我以前收集的一篇文章，找不到出处了，稍作修改在此发布）</p>
<p><br class="spacer_" /></p>
<p>如果你发现程序的bug，但每次进行测试都需要许多步骤才能重现问题，那么本教程适合你。通常，测试和调试是非常繁琐的事情，iPhone程序的开发尤其如此。</p>
<p><span id="more-970"></span><br class="spacer_" /></p>
<p>比如说，你有个程序需要经过5个步骤才能到达另一个view。如果你有一个bug发生在这个需要5步之多的view上，通常情况下调试的步骤如下：</p>
<ul>
<li>运行程序</li>
<li>触击 view 1</li>
<li>触击view 2</li>
<li>触击 view 3</li>
<li>触击 view 4</li>
<li>触击 view 5</li>
<li>(程序崩溃)</li>
<li>修改代码</li>
<li>重复以上步骤</li>
</ul>
<p><br class="spacer_" /></p>
<p>如你所见，这是多么痛苦的事情啊。 <a href="http://twitter.com/kendalldevdiary">Kendall Gelner</a> 在 <a href="http://www.360idev.com/">360iDev</a> 上有关使用Instruments 和 XCode进行调试的若干提示的演讲中，对我而言最为有用的就是将测试自动化。我演示一下应该怎么做:</p>
<p style="padding-left: 30px;">1. 打开希望测试/调试的程序</p>
<p style="padding-left: 30px;">2. 在模拟器中运行</p>
<p style="padding-left: 30px;">3. 打开<strong>Instrument</strong> – 位于 /Developer/<a id="KonaLink2" style="position: static; text-decoration: underline !important;" onclick="adlinkMouseClick(event,this,2);" onmouseover="adlinkMouseOver(event,this,2);" onmouseout="adlinkMouseOut(event,this,2);" href="http://www.iphone-geek.cn/wp-admin/#" target="_new"><span style="position: static; color: #346200 !important; font-weight: 400;"><span style="position: static; font-family: Helvetica, Arial, sans-serif; color: #346200 !important; font-weight: 400;">Applications</span></span></a>/Instruments</p>
<ol> </ol>
<ol> </ol>
<p><br class="spacer_" /></p>
<p style="text-align: center;"><strong><a href="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_01.png"><img class="aligncenter" style="zoom: 1; display: inline;" title="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_01-300x229.png" alt="screenshot_01" width="300" height="229" /></a></strong></p>
<p style="text-align: center;"><strong><br />
 </strong></p>
<p style="padding-left: 30px;">4. 选择 <strong>UIRecorder</strong> 并按<strong>Choose </strong>- 你将看到下面窗口</p>
<p style="text-align: center;"><strong><a href="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_02.png"><img class="aligncenter" style="zoom: 1; display: inline;" title="screenshot_02" src="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_02-300x211.png" alt="screenshot_02" width="300" height="211" /></a></strong></p>
<p style="text-align: center;"><strong><br />
 </strong></p>
<p style="padding-left: 30px;">5.  然后需要将此工具与iPhone模拟器进程链接。按下下拉菜单选择 <strong>Default Target</strong> -&gt; <strong>Attach to Process </strong>-&gt; <strong>iPhone Simulator</strong>.</p>
<p style="text-align: center;"><a href="http://icodeblog.com/wp-content/uploads/2009/10/ss_03.png"><img class="aligncenter" style="zoom: 1; display: inline;" title="ss_03" src="http://icodeblog.com/wp-content/uploads/2009/10/ss_03-300x136.png" alt="ss_03" width="300" height="136" /></a></p>
<p><br class="spacer_" /></p>
<p style="padding-left: 30px;">6. 再按下 <strong>Drive &amp; Record</strong> 并在模拟器中完成测试所需的所有步骤。至此，UI Recorder记录下了你的一举一动。完成时，按下<strong>Stop</strong>按钮。 <span style="color: #ff0000;"><strong>注意：</strong></span> 在完成记录后请不要移动模拟器，因为这有可能会使弄乱整个处理过程。</p>
<p style="padding-left: 30px;">7. 修改你的代码…</p>
<p style="padding-left: 30px;">8. 按下 <strong>Drive &amp; Record </strong>按钮亲眼目睹一下有什么神奇的事情发生吧。测试自动进行了！你应该看到它自动模拟了你刚才进行的所有动作。</p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b0%83%e8%af%95%e6%95%99%e7%a8%8b-%e2%80%93-%e4%bd%bf%e7%94%a8uirecorder-instrument%e5%b0%86%e6%b5%8b%e8%af%95%e8%87%aa%e5%8a%a8%e5%8c%96/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>真机安装测试iPhone应用程序</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e7%9c%9f%e6%9c%ba%e5%ae%89%e8%a3%85%e6%b5%8b%e8%af%95iphone%e5%ba%94%e7%94%a8%e7%a8%8b%e5%ba%8f</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e7%9c%9f%e6%9c%ba%e5%ae%89%e8%a3%85%e6%b5%8b%e8%af%95iphone%e5%ba%94%e7%94%a8%e7%a8%8b%e5%ba%8f#comments</comments>
		<pubDate>Sat, 10 Apr 2010 03:04:33 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[系统安装]]></category>
		<category><![CDATA[初学者]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=929</guid>
		<description><![CDATA[前两天有朋友问我有关怎样在真机上加载和调试iPhone程序的问题，实际上有两个方法：

1. 申请ADC帐号，购买iDP（iPhone Develop Program）
2. 在“越狱”的iPhone上安装程序

本准备写一篇教程，但在网上搜了一下，找到一些链接，为尊重原作者的劳动，这里我仅给出链接（但是否是原始链接，我就不得而知了，因为有许多网站并未表明原始地址。对此，小小地鄙视一下！）

从零开始开发iPhone，教你如何在真机调试iPhone应用程序

简单明了SDK2.2.1无99刀证书真机运行方法图文教程
]]></description>
			<content:encoded><![CDATA[<p>前两天有朋友问我有关怎样在真机上加载和调试iPhone程序的问题，实际上有两个方法：</p>
<p><br class="spacer_" /></p>
<p>1. 申请ADC帐号，购买iDP（iPhone Develop Program）</p>
<p>2. 在“越狱”的iPhone上安装程序</p>
<p><br class="spacer_" /></p>
<p>本准备写一篇教程，但在网上搜了一下，找到一些链接，为尊重原作者的劳动，这里我仅给出链接（但是否是原始链接，我就不得而知了，因为有许多网站并未表明原始地址。对此，小小地鄙视一下！）</p>
<p><br class="spacer_" /></p>
<p><a href="http://blog.csdn.net/dotphoenix/archive/2010/01/30/5271727.aspx"><strong>从零开始开发iPhone，教你如何在真机调试iPhone应用程序</strong></a></p>
<p><br class="spacer_" /></p>
<p><a href="http://www.cocoachina.com/iphonedev/sdk/2009/0611/280.html"><strong>简单明了SDK2.2.1无99刀证书真机运行方法图文教程</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e7%9c%9f%e6%9c%ba%e5%ae%89%e8%a3%85%e6%b5%8b%e8%af%95iphone%e5%ba%94%e7%94%a8%e7%a8%8b%e5%ba%8f/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone不是Mac Pro</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e4%b8%8d%e6%98%afmac-pro</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e4%b8%8d%e6%98%afmac-pro#comments</comments>
		<pubDate>Tue, 09 Feb 2010 05:21:03 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[提示与技巧]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=359</guid>
		<description><![CDATA[本文是关于通过Objective C++的强大功能提高iPhone程序的性能。通过讨论现实世界中Savoy的Spots应用程序遇到的问题，本文展示了通过3个步骤对程序进行优化使其顺利运行的过程。




使用Objective C++提高iPhone应用程序的性能

我十分喜爱软件开发的一个原因是总是会遇到这样那样的问题，而总能找到相应的解决方法。在开发Spots时，我多次遇到了UI设计的问题。为  iPhone设计一个精简的用户界面是不容易的。比如，我应该提供一个提供者过滤器（指Hotspot）按钮或将其放在Settings.app中？关于这个问题，我至少改变了二十次主意？

本文不是关于用户界面设计而是有关编程与性能。本文并不是针对用户界面而是有关编程和性能。一个最大的难题是地图的绘制（屏幕下方的长方形）。经过几种方法的试用，我发现在绘制230，000个点时，只有使用OpenGL以及大量的旁门左道才能使绘图的性能勉强被接受。根据放大的级别以及可见点点数量，我最后使用了三种不同的技术。由于我需要地图交互动作（拖动和缩放）尽可能地平滑，理想情况下为60HZ，性能是最为重要的问题。



本文中我将分享一些能提高性能的技术。虽然它们都很简单和直接，但因为在Cocoa中很少见，所以我还是花了不少时间。例如，尽管C++和Objective  C可以非常高效地混合使用，但我在Cocoa中并没有见到许多C++。当你的目标是高性能时，Objective  C++是纯Cocoa的很好的扩展。而在iPhone上，性能是应该首先需要考虑到因素。

难题

对于分布在一个矩形区域包括230，000个热点位置的地图（麦卡托投影的世界地图 the world map in mercator  projection），首先必须清楚当前地图矩形区域中有多少个可见点，因为此数值可以决定使用何种绘图技术。指标值必须归一，因此整个地图覆盖了一个{{0.0,  1.0}, {0.0, 1.0}}的矩形区域。通常情况下，程序使用的地图矩形是很小的：通常小于整个地图宽度和高度的百分之二。




但是我怎样有效地在数据库成千上万的点中找到可见点的数量？

我准备了一个XCode项目，它包括了这里讨论的所有代码。此示例项目并未包括了所有点的原始数据库。它仅包含了一些世界地图上的随机数据。虽然与真实情况有所区别，但它们的处理方法与我收集的原始数据的大同小异。

第一种方法: 普通Cocoa方法

第一种方法十分简单而且并没有采用十分高效的方法。使用Object C对象（@class  Spot）来表示位置，它们以NSArrary的形式被保存在一个数据库对象中（@class SpotsDB1）。
@interface Spot : NSObject {
    CGPoint _position;
}
@property (nonatomic) CGPoint position;
@end

@interface SpotsDB1 : NSObject {
    NSArray* _spots;
}
- (NSUInteger)countSpotsInRect:(CGRect)rect;
@end

为进行一个指定CGRect内地位置计数，数据库对象简单地循环整个数组并检查各位置。

NSUInteger count = 0;
 for (Spot* spot in _spots) {
 [...]]]></description>
			<content:encoded><![CDATA[<p>本文是关于通过Objective C++的强大功能提高iPhone程序的性能。通过讨论现实世界中Savoy的<a href="http://www.savoysoftware.com/spots/">Spots</a>应用程序遇到的问题，本文展示了通过3个步骤对程序进行优化使其顺利运行的过程。</p>
<p><br class="spacer_" /></p>
<p><a href="http://www.savoysoftware.com/spots/"><img title="spots-icon-big" src="http://savoysoftware.com/blog/wp-content/uploads/2008/12/spots-icon-big.png" alt="Spots" width="165" height="165" /></a></p>
<p><br class="spacer_" /></p>
<p><img title="More..." src="../wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span id="more-359"></span></p>
<h3><strong>使用Objective C++提高iPhone应用程序的性能</strong></h3>
<p><br class="spacer_" /></p>
<p>我十分喜爱软件开发的一个原因是总是会遇到这样那样的问题，而总能找到相应的解决方法。在开发Spots时，我多次遇到了UI设计的问题。为  iPhone设计一个精简的用户界面是不容易的。比如，我应该提供一个提供者过滤器（指Hotspot）按钮或将其放在Settings.app中？关于这个问题，我至少改变了二十次主意？</p>
<p><br class="spacer_" /></p>
<p>本文不是关于用户界面设计而是有关编程与性能。本文并不是针对用户界面而是有关编程和性能。一个最大的难题是地图的绘制（屏幕下方的长方形）。经过几种方法的试用，我发现在绘制230，000个点时，只有使用OpenGL以及大量的旁门左道才能使绘图的性能勉强被接受。根据放大的级别以及可见点点数量，我最后使用了三种不同的技术。由于我需要地图交互动作（拖动和缩放）尽可能地平滑，理想情况下为60HZ，性能是最为重要的问题。</p>
<p><br class="spacer_" /></p>
<p><img title="map_spots" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/map_spots.png" alt="map_spots" width="320" height="211" /></p>
<p><br class="spacer_" /></p>
<p>本文中我将分享一些能提高性能的技术。虽然它们都很简单和直接，但因为在Cocoa中很少见，所以我还是花了不少时间。例如，尽管C++和Objective  C可以非常高效地混合使用，但我在Cocoa中并没有见到许多C++。当你的目标是高性能时，Objective  C++是纯Cocoa的很好的扩展。而在iPhone上，性能是应该首先需要考虑到因素。</p>
<p><br class="spacer_" /></p>
<h4><strong>难题</strong></h4>
<p><br class="spacer_" /></p>
<p>对于分布在一个矩形区域包括230，000个热点位置的地图（麦卡托投影的世界地图 the world map in mercator  projection），首先必须清楚当前地图矩形区域中有多少个可见点，因为此数值可以决定使用何种绘图技术。指标值必须归一，因此整个地图覆盖了一个{{0.0,  1.0}, {0.0, 1.0}}的矩形区域。通常情况下，程序使用的地图矩形是很小的：通常小于整个地图宽度和高度的百分之二。</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p><img title="map" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/map.png" alt="map" width="453" height="343" /></p>
<p><br class="spacer_" /></p>
<p>但是我怎样有效地在数据库成千上万的点中找到可见点的数量？</p>
<p><br class="spacer_" /></p>
<p>我准备了一个<a href="http://savoysoftware.com/blog/wp-content/uploads/2009/01/spotsdb.zip">XCode项目</a>，它包括了这里讨论的所有代码。此示例项目并未包括了所有点的原始数据库。它仅包含了一些世界地图上的随机数据。虽然与真实情况有所区别，但它们的处理方法与我收集的原始数据的大同小异。</p>
<p><br class="spacer_" /></p>
<h5>第一种方法: 普通Cocoa方法</h5>
<p><br class="spacer_" /></p>
<p>第一种方法十分简单而且并没有采用十分高效的方法。使用Object C对象（@class  Spot）来表示位置，它们以NSArrary的形式被保存在一个数据库对象中（@class SpotsDB1）。</p>
<pre>@interface Spot : NSObject {
    CGPoint _position;
}
@property (nonatomic) CGPoint position;
@end

@interface SpotsDB1 : NSObject {
    NSArray* _spots;
}
- (NSUInteger)countSpotsInRect:(CGRect)rect;
@end</pre>
<p><br class="spacer_" /></p>
<p>为进行一个指定CGRect内地位置计数，数据库对象简单地循环整个数组并检查各位置。</p>
<p><br class="spacer_" /></p>
<p>NSUInteger count = 0;<br />
 for (Spot* spot in _spots) {<br />
 if  (CGRectContainsPoint(aRect, spot.position))<br />
 ++count;<br />
 }</p>
<p><br class="spacer_" /></p>
<p>使用上述代码，在总数为230，000个点的区域上的任意一个{0.02,  0.02}矩形内进行计数大概需要250毫秒。太糟糕了，如果你的目标是刷新率60Hz，那么你只有16  ms绘制一帧。使得此方案过慢的原因不仅在于其缺乏聪明的算法，而且在循环中浪费了许多时间在调用了几个函数上。另一个对性能产生负面影响的因素是位置被保存在NSArray中的对象，这是由于对象占用了大量的内存以及数组指针的非直接性导致了处理器时间的增加。</p>
<p><br class="spacer_" /></p>
<h5>第二种方法: 简单优化</h5>
<p><br class="spacer_" /></p>
<p>为使同样的方案运行得更快，我们只需简单地将位置存储与一个更为紧凑的数据结构中：一个CGPoint结构的标准C数组。为使用方便，我们将C数组保存在一个NSMutableData  对象中。</p>
<p><br class="spacer_" /></p>
<p>_spotCount = [spots count];<br />
 _spotsData = [[NSMutableData alloc]  init];<br />
 for (Spot* spot in spots) {<br />
 CGPoint p = spot.position;<br />
 [data appendBytes:&amp;p length:sizeof(CGPoint)];<br />
 }</p>
<p><br class="spacer_" /></p>
<p>消除了循环内函数调用的负面影响，我们使得性能有四倍的提升：</p>
<p><br class="spacer_" /></p>
<p>CGFloat xMin = CGRectGetMinX(aRect);<br />
 CGFloat yMin =  CGRectGetMinY(aRect);<br />
 CGFloat xMax = CGRectGetMaxX(aRect);<br />
 CGFloat yMax =  CGRectGetMaxY(aRect);</p>
<p>CGPoint* begin = (CGPoint*)[_spotsData  bytes];<br />
 CGPoint* end = begin + _spotCount;</p>
<p>NSUInteger count =  0;<br />
 for (CGPoint* i = begin; i != end; ++i) {<br />
 if (i-&gt;x &gt; xMin  &amp;&amp; i-&gt;y &gt; yMin &amp;&amp; i-&gt;x &lt; xMax &amp;&amp; i-&gt;y  &lt; yMax)<br />
 ++count;<br />
 }</p>
<p><br class="spacer_" /></p>
<p>在没有改变基本算法的基础上，点计数的计算现在只需55毫秒，这大概比原来方法快了四倍。另一个好处是现在使用的内存是原来版本的一半。</p>
<h5>第三种方法：算法优化</h5>
<p><br class="spacer_" /></p>
<p>当然，还有许多聪明的方法来优化平面地图点的查询。例如，你可以使用四边形树来保存这些点。在本例中我使用了一种比较简单的解决方案，所以没有涉及数据存储的方式。我使用了C++的内置功能所以甚至不需要写任何代码来处理数据的存储。</p>
<p><br class="spacer_" /></p>
<p><img title="sorted" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/sorted.png" alt="sorted" width="355" height="343" /></p>
<p><br class="spacer_" /></p>
<p>我的设想是将数组中的位置从左至右分类。这样做的好处是确定指定正方形的左右边界十分快速（见下图）。当数组中边界已知时，仅需要检查边界间的点。</p>
<p><br class="spacer_" /></p>
<p><img title="sorted2" src="http://savoysoftware.com/blog/wp-content/uploads/2009/01/sorted2.png" alt="sorted2" width="355" height="343" /></p>
<p><br class="spacer_" /></p>
<p>所以此算法是有关快速寻找边界的。我们使用的是<a href="http://en.wikipedia.org/wiki/Binary_search">二进制搜索</a>，  它适用于已排序的数组。它并不检查每个值以找到匹配的位置，而是直接跳到数组的中点，检查其值是小于还是大于给点值，然后跳到剩余部分的中心点，重复以上步骤。使用这种方法，二进制搜索需要  log2(n)的时间来查找最佳元素。对于一个拥有230，000个位置的数组，只需22次搜索！回到代码，我们发现上述算法的实现是很简单的。当然，我们必须为数据库排序：</p>
<pre>// comparison function for array sorting
NSInteger leftToRight(Spot* a, Spot* b, void* context) {
    CGFloat xa = a.position.x;
    CGFloat xb = b.position.x;
    if (xa &lt; xb)
        return NSOrderedAscending;
    return xa &gt; xb ? NSOrderedDescending : NSOrderedSame;
}

...

spots = [spots sortedArrayUsingFunction:leftToRight context:NULL];</pre>
<p><br class="spacer_" /></p>
<p>现在是有趣的部分：使用C++进行二进制搜索。我们使用了#include &lt;algorithm&gt;中的库函数  std::lower_bound。它需要一个起点，终点，要查找的值以及比较函数。它返回比较为false的第一个值。起点和终点可以是简单的<span style="font-family: 微软雅黑;">指向数组的C指针。</span></p>
<p><br class="spacer_" /></p>
<p>#include &lt;algorithm&gt;<br />
 &#8230;</p>
<p>bool cmpX(const  CGPoint&amp; a, const CGPoint&amp; b) {<br />
 return a.x &lt;  b.x;<br />
 }<br />
 &#8230;</p>
<p>CGFloat yMin = CGRectGetMinY(aRect);<br />
 CGFloat yMax =  CGRectGetMaxY(aRect);</p>
<p>CGPoint* begin = (CGPoint*)[_spotsData  bytes];<br />
 CGPoint* end = begin + _spotCount;</p>
<p>CGPoint leftMargin =  aRect.origin;<br />
 CGPoint rightMargin;<br />
 rightMargin.x =  CGRectGetMaxX(aRect);</p>
<p>CGPoint* left  = std::lower_bound(begin, end,  leftMargin, cmpX);<br />
 CGPoint* right = std::lower_bound(left, end, rightMargin,  cmpX);</p>
<p>NSUInteger count = 0;<br />
 for (CGPoint* i = left; i != right; ++i)  {<br />
 if (i-&gt;y &gt; yMin &amp;&amp; i-&gt;y &lt; yMax)<br />
 ++count;<br />
 }</p>
<p><br class="spacer_" /></p>
<p>注意第二个二进制搜索，它仅从左边界而不是整个数组查找右边界。另一个优化是从循环中移除X-轴的检查，这是因为已经通过指定边界完成了这部分工作。</p>
<p><br class="spacer_" /></p>
<p>通过这些优化，只需要1毫秒来对长方形进行计数。这是第一个版本的200倍。</p>
<h5>结果</h5>
<p><br class="spacer_" /></p>
<p>下面是运行在三种不同设备上的<a href="http://savoysoftware.com/blog/wp-content/uploads/2009/01/spotsdb.zip">示例项目</a>的输出。如果你需要运行在你自己的设备上，你只需将目标设定中将代码签名标识符改为自己的。如果你不希望用在通用标识符的程序上，你还需要更改Info.plist中的包标识符（Bundle  Identifier）。</p>
<p><br class="spacer_" /></p>
<p>iPhone 3G：</p>
<pre>SpotsDB1 needed 3.2 seconds to count spots in 13 rects
that's 244.423 ms per rect
SpotsDB2 needed 3.0 seconds to count spots in 55 rects
that's 55.230 ms per rect
SpotsDB3 needed 3.0 seconds to count spots in 2988 rects
that's 1.004 ms per rect</pre>
<p>第二代iPod Touch：</p>
<pre>SpotsDB1 needed 3.1 seconds to count spots in 16 rects
that's 194.756 ms per rect
SpotsDB2 needed 3.0 seconds to count spots in 65 rects
that's 46.450 ms per rect
SpotsDB3 needed 3.0 seconds to count spots in 3399 rects
that's 0.883 ms per rect</pre>
<p>运行在Mac Pro之上的模拟器：</p>
<pre>SpotsDB1 needed 3.0 seconds to count spots in 687 rects
that's 4.372 ms per rect
SpotsDB2 needed 3.0 seconds to count spots in 2687 rects
that's 1.117 ms per rect
SpotsDB3 needed 3.0 seconds to count spots in 187276 rects
that's 0.016 ms per rect</pre>
<h5>结论</h5>
<p><br class="spacer_" /></p>
<p>观察结果我们可以看出在桌面电脑和iPhone上性能有显著的区别。有一个金科玉律是：在Mac上只需一秒的操作在iPhone上要一分钟。或者有一个更悲观的说法：Mac上60Hz的刷新率在iPhone上每秒钟只能更新一次。</p>
<p><br class="spacer_" /></p>
<p>所以显而易见在iPhone上进行优化是完全必须的。本文中我展示了几种方法来减小Object  C的开销以及怎样使用C++来获得最大的性能。当然找到性能的瓶颈并转而使用数据结构使代码性能提升并不总是很容易的事情。但是在设计一个使用大量数据的程序时，绝对有必要考虑使用非Cocoa的方法。</p>
<h6>原文见：<a href="http://www.savoysoftware.com/blog/?p=114">My iPhone is not a  Mac Pro</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e4%b8%8d%e6%98%afmac-pro/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone程序的文档目录</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95#comments</comments>
		<pubDate>Thu, 04 Feb 2010 06:09:12 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=868</guid>
		<description><![CDATA[最近实在太忙，手头上的事情还没有完成，因此正在进行的几篇有关OpenGL ES的文章只能推后了。

今天介绍一下怎样获得iPhone程序的文档目录（通常用来存储用户数据），方法一：

12NSString* documentsDirectory &#160;= &#91;NSHomeDirectory&#40;&#41; 
&#160; &#160; &#160; &#160; stringByAppendingPathComponent:@&#34;Documents&#34;&#93;;

方法二：

12NSArray *paths = NSSearchPathForDirectoriesInDomains&#40;NSDocumentDirectory, NSUserDomainMask, YES&#41;; 
NSString *documentsDirectory = &#91;paths objectAtIndex:0&#93;;
]]></description>
			<content:encoded><![CDATA[<p>最近实在太忙，手头上的事情还没有完成，因此正在进行的几篇有关OpenGL ES的文章只能推后了。</p>
<p><br class="spacer_" /></p>
<p>今天介绍一下怎样获得iPhone程序的文档目录（通常用来存储用户数据），方法一：</p>
<p><br class="spacer_" /></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> documentsDirectory &nbsp;<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSHomeDirectory<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; stringByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Documents&quot;</span><span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<p><br class="spacer_" /></p>
<p>方法二：</p>
<p><br class="spacer_" /></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> <span style="color: #002200;">*</span>paths <span style="color: #002200;">=</span> NSSearchPathForDirectoriesInDomains<span style="color: #002200;">&#40;</span>NSDocumentDirectory, NSUserDomainMask, <span style="color: #a61390;">YES</span><span style="color: #002200;">&#41;</span>; <br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>documentsDirectory <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>paths objectAtIndex<span style="color: #002200;">:</span>0<span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e7%a8%8b%e5%ba%8f%e7%9a%84%e6%96%87%e6%a1%a3%e7%9b%ae%e5%bd%95/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>跨平台代码分享之七 &#8211; 一个简单的音效引擎</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e4%b8%83-%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e9%9f%b3%e6%95%88%e5%bc%95%e6%93%8e</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e4%b8%83-%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e9%9f%b3%e6%95%88%e5%bc%95%e6%93%8e#comments</comments>
		<pubDate>Wed, 06 Jan 2010 06:18:19 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[音频]]></category>
		<category><![CDATA[跨平台]]></category>
		<category><![CDATA[OpenAL]]></category>
		<category><![CDATA[开源项目]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=727</guid>
		<description><![CDATA[游戏都需要一个声音引擎，一般来说，有三种类型：

播放音效。音效一般是比较简短的声音文件。
播放背景音乐。
乐器，音效模拟。

&#160;
本文介绍一个简单跨平台的音效引擎，主要针对第一种类型。实际上，也可以适用于第二种类型，但由于背景音乐文件较大，占用内存较大，所以本文介绍的方法并不是最为有效率的（特别是对于像iPhone之类内存较为紧张的平台，但仍然可用）。可以在本引擎的基础上加以改进，比如采用“流”（streaming）技术。而第三种类型，可能涉及到DSP（数字处理技术），比较复杂，另外在不同平台有一些不同的技术，如Windows下的VST/VSTi，Mac OSX下的AU等，不在本文的讨论范围。
&#160;
本文介绍的音效引擎是基于OpenAL的，并且是我在许多项目中使用的引擎的简化部分（去除错误处理及乐器模拟部分）。
&#160;
有关OpenAL的使用，网上有许多教程，比如：OpenAL编程教程等。iPhone上的OpenAL使用，本网站也有几篇文章。所以这里不再赘述。
&#160;
本引擎的目的，是简化声音播放接口。最简单的情况下可以仅仅使用两条语句，就播放一段音效。而繁复的OpenAL初始化功能等都由引擎自动完成。下例展示了怎样播放一段音效的最为典型的调用：
&#160;
123audio::CSound sound&#40;&#34;sound.wav&#34;&#41;;

sound.play&#40;&#41;;
&#160;
本引擎由三个类和一个公共函数构成。audio::CEngine是引擎的核心部分，它是一个单例类（Singleton)，负责直接与OpenAL接口，用户无需与其打交道。audio::CBuffer类对应于OpenAL中的缓存，通过audio::openAudioData函数打开音效文件，创建内部缓存，用户也无需直接使用。audio::CSound是用户直接使用的类，它提供了诸如play（），stop（），setVolume（）和setPosition（）几个接口函数。如需扩展功能，添加一些其他功能，可以直接加在此类中，并在audio::CEngine中实现。
&#160;
以上三个类可以直接使用在不同平台中。与平台相关的代码，都在audio::openAudioData()中。它的作用是打开不同的声音文件。对于Windows，我使用了一个开源项目库libsndfile，用来打开诸如wav，caf，aiff，flac，ogg等常用音效文件（注意：mp3并未包括其中。由于使用mp3的软件需要支付一定许可证费用，本人也不喜欢使用）。而对于Mac OSX（iPhone），则使用了core audio。这里大家可能会有一个疑问，既然libsndfile也是跨平台的，为什么在iPhone上不使用它呢？确实，libsndfile支持Windows，Linux，Mac OSX，Sun Solaris等平台，而iPhone并不支持ogg等格式，使用libsndfile不正好填补这个空白？是的，我也是这样想的，但是，有两点原因初始我暂时没有使用它：

没有现成的iPhone库。由于libsndfile需要使用makefile由GCC编译（我曾试过使用Xcode编译，没有成功），我也不是这方面的专家。但是，libsndfile在Mac OSX下编译没有问题，所以只需稍作修改，在为iPhone进行编译也不是没有可能的事情。
由于其许可证的限制。libsndfile是基于LGPL的，它要求使用者采用动态连接库，而众所周知，iPhone（官方）是不支持动态链接的。如果使用静态链接，则需要随软件发布源代码或目标代码。其实，这也不是无法克服的，LGPL只要求发布与libsnd相关的目标代码，所以对你的软件并无影响。对吗？

&#160;
本文给出了Windows下和iPhone下的应用。在Windows下使用需要下载OpenAL SDK和libsndfile。为方便编译好的libsndfile随示例程序给出给出。（你需要修改一下VS 项目文件中的有关OpenAL的头文件和库文件路径，另外，在OpenAL include目录中创建一个OpenAL目录，并将.h复制到其下，这样我就不需要修改#include语句了。）
&#160;
示例程序audiolib下载。（项目在test目录下）
]]></description>
			<content:encoded><![CDATA[<p>游戏都需要一个声音引擎，一般来说，有三种类型：</p>
<ol>
<li>播放音效。音效一般是比较简短的声音文件。</li>
<li>播放背景音乐。</li>
<li>乐器，音效模拟。</li>
</ol>
<p>&nbsp;</p>
<p>本文介绍一个简单跨平台的音效引擎，主要针对第一种类型。实际上，也可以适用于第二种类型，但由于背景音乐文件较大，占用内存较大，所以本文介绍的方法并不是最为有效率的（特别是对于像iPhone之类内存较为紧张的平台，但仍然可用）。可以在本引擎的基础上加以改进，比如采用“流”（streaming）技术。而第三种类型，可能涉及到DSP（数字处理技术），比较复杂，另外在不同平台有一些不同的技术，如Windows下的VST/VSTi，Mac OSX下的AU等，不在本文的讨论范围。</p>
<p>&nbsp;</p>
<p>本文介绍的音效引擎是基于OpenAL的，并且是我在许多项目中使用的引擎的简化部分（去除错误处理及乐器模拟部分）。</p>
<p>&nbsp;</p>
<p>有关OpenAL的使用，网上有许多教程，比如：<a href="http://www.devmaster.net/articles/openal-tutorials/lesson1.php">OpenAL编程教程</a>等。iPhone上的OpenAL使用，本网站也有几篇文章。所以这里不再赘述。</p>
<p>&nbsp;</p>
<p>本引擎的目的，是简化声音播放接口。最简单的情况下可以仅仅使用两条语句，就播放一段音效。而繁复的OpenAL初始化功能等都由引擎自动完成。下例展示了怎样播放一段音效的最为典型的调用：</p>
<p>&nbsp;</p>
<div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">audio<span style="color: #008080;">::</span><span style="color: #007788;">CSound</span> sound<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;sound.wav&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<br />
sound.<span style="color: #007788;">play</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>本引擎由三个类和一个公共函数构成。audio::CEngine是引擎的核心部分，它是一个单例类（Singleton)，负责直接与OpenAL接口，用户无需与其打交道。audio::CBuffer类对应于OpenAL中的缓存，通过audio::openAudioData函数打开音效文件，创建内部缓存，用户也无需直接使用。audio::CSound是用户直接使用的类，它提供了诸如play（），stop（），setVolume（）和setPosition（）几个接口函数。如需扩展功能，添加一些其他功能，可以直接加在此类中，并在audio::CEngine中实现。</p>
<p>&nbsp;</p>
<p>以上三个类可以直接使用在不同平台中。与平台相关的代码，都在audio::openAudioData()中。它的作用是打开不同的声音文件。对于Windows，我使用了一个开源项目库<a href="http://www.mega-nerd.com/libsndfile/">libsndfile</a>，用来打开诸如wav，caf，aiff，flac，ogg等常用音效文件（<strong>注意：mp3并未包括其中。由于使用mp3的软件需要支付一定许可证费用，本人也不喜欢使用</strong>）。而对于Mac OSX（iPhone），则使用了core audio。这里大家可能会有一个疑问，既然libsndfile也是跨平台的，为什么在iPhone上不使用它呢？确实，libsndfile支持Windows，Linux，Mac OSX，Sun Solaris等平台，而iPhone并不支持ogg等格式，使用libsndfile不正好填补这个空白？是的，我也是这样想的，但是，有两点原因初始我暂时没有使用它：</p>
<ol>
<li>没有现成的iPhone库。由于libsndfile需要使用makefile由GCC编译（我曾试过使用Xcode编译，没有成功），我也不是这方面的专家。但是，libsndfile在Mac OSX下编译没有问题，所以只需稍作修改，在为iPhone进行编译也不是没有可能的事情。</li>
<li>由于其许可证的限制。libsndfile是基于LGPL的，它要求使用者采用动态连接库，而众所周知，iPhone（官方）是不支持动态链接的。<strong>如果使用静态链接，则需要随软件发布源代码或目标代码。</strong>其实，这也不是无法克服的，LGPL只要求发布与libsnd相关的目标代码，所以对你的软件并无影响。对吗？</li>
</ol>
<p>&nbsp;</p>
<p>本文给出了Windows下和iPhone下的应用。在Windows下使用需要下载<a href="http://connect.creativelabs.com/openal/Downloads/oalinst.zip">OpenAL SDK</a>和<a href="http://www.mega-nerd.com/libsndfile/">libsndfile</a>。为方便编译好的libsndfile随示例程序给出给出。（你需要修改一下VS 项目文件中的有关OpenAL的头文件和库文件路径，另外，在OpenAL include目录中创建一个OpenAL目录，并将.h复制到其下，这样我就不需要修改#include语句了。）</p>
<p>&nbsp;</p>
<p>示例程序<a href="../wp-content/uploads/2010/01/audiolib.zip">audiolib</a>下载。（项目在test目录下）<a href="http://www.iphone-geek.cn/wp-content/uploads/2010/01/audiolib.zip"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e4%b8%83-%e4%b8%80%e4%b8%aa%e7%ae%80%e5%8d%95%e7%9a%84%e9%9f%b3%e6%95%88%e5%bc%95%e6%93%8e/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Poco C++ for iPhone之一 &#8211; 编译</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/poco-c-for-iphone%e4%b9%8b%e4%b8%80-%e7%bc%96%e8%af%91</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/poco-c-for-iphone%e4%b9%8b%e4%b8%80-%e7%bc%96%e8%af%91#comments</comments>
		<pubDate>Tue, 29 Dec 2009 02:39:58 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[跨平台]]></category>
		<category><![CDATA[开源项目]]></category>
		<category><![CDATA[源代码]]></category>
		<category><![CDATA[代码片段]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=554</guid>
		<description><![CDATA[Poco C++是一个强大的跨平台C++库，你可以在iPhone程序中使用它，如果：

你打算使你的程序跨平台。
你喜欢使用C++或希望使用Poco C++中的功能如：XML，Zip等。

&#160;
目前，最新Poco C++版本为1.3.6P1，根据文档，它可以编译为iPhone静态库。但是我试用了一下，无法使用在iPhone Xcode项目中链接，不知何故。所以我自己创建了下列Xcode项目：

Poco Foundation
Poco Util
Poco Net
Poco XML
Poco Zip

&#160;
另外，由于Crypto，Data，NetSSL_OpenSSL库需要外部库而且目前我不需要使用，所以没有包括。另外我增加了一个目录iPhoneSamples，它目前包括了一个示例程序HelloPoco，演示了怎样在iPhone项目中使用Poco C++库（此演示程序十分简单，它调用Poco中的UUID功能，产生一个UUID，显示与屏幕上）。下面是包括了此展示程序以及各Xcode文件的Poco包的下载：
&#160;
poco-1.3.6p1
]]></description>
			<content:encoded><![CDATA[<p>Poco C++是一个强大的跨平台C++库，你可以在iPhone程序中使用它，如果：</p>
<ol>
<li>你打算使你的程序跨平台。</li>
<li>你喜欢使用C++或希望使用Poco C++中的功能如：XML，Zip等。</li>
</ol>
<p>&nbsp;</p>
<p>目前，最新Poco C++版本为1.3.6P1，根据文档，它可以编译为iPhone静态库。但是我试用了一下，无法使用在iPhone Xcode项目中链接，不知何故。所以我自己创建了下列Xcode项目：</p>
<ul>
<li>Poco Foundation</li>
<li>Poco Util</li>
<li>Poco Net</li>
<li>Poco XML</li>
<li>Poco Zip</li>
</ul>
<p>&nbsp;</p>
<p>另外，由于Crypto，Data，NetSSL_OpenSSL库需要外部库而且目前我不需要使用，所以没有包括。另外我增加了一个目录iPhoneSamples，它目前包括了一个示例程序HelloPoco，演示了怎样在iPhone项目中使用Poco C++库（此演示程序十分简单，它调用Poco中的UUID功能，产生一个UUID，显示与屏幕上）。下面是包括了此展示程序以及各Xcode文件的Poco包的下载：</p>
<p>&nbsp;</p>
<p><a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/poco-1.3.6.zip">poco-1.3.6p1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/poco-c-for-iphone%e4%b9%8b%e4%b8%80-%e7%bc%96%e8%af%91/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>跨平台代码分享之六 &#8211; 使用minizip进行解压</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e5%85%ad-%e4%bd%bf%e7%94%a8minizip%e8%bf%9b%e8%a1%8c%e8%a7%a3%e5%8e%8b</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e5%85%ad-%e4%bd%bf%e7%94%a8minizip%e8%bf%9b%e8%a1%8c%e8%a7%a3%e5%8e%8b#comments</comments>
		<pubDate>Wed, 23 Dec 2009 10:56:03 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[跨平台]]></category>
		<category><![CDATA[压缩解压]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=451</guid>
		<description><![CDATA[压缩和解压技术应用很广泛，比如游戏程序中的资源管理器可以使用压缩技术将许多文件打包，便于管理，也节约了空间。本文介绍使用minizip进行解压。由于可以使用zip工具比如winzip，betterzip等进行压缩，所以本文并未涉及压缩。
&#160;

minizip++
&#160;
我编写了一个简单的类，与minizip和zlib一起（实际上，Mac OSX中包括了zlib库，但其他平台不一定有zlib库，所以我将其包括在源码中），构成了minizip++。此类仅包含一个类zip::CReader，此类只包括一个函数openFile用于从zip文件中读取一个文件。
&#160;
范例概述
&#160;
本示例程序很简单，它从data.zip文件中提取data/hello.txt显示于屏幕上，有兴趣的话，你可以扩展此程序，从zip中提取图像然后显示出来。
&#160;
废话少说，下面介绍程序：

1. 先建立一个View based Xcode项目ziptest，再创建一个目录data，在此目录下建立一个文本文件hello.txt，编辑此文本文件，加入你想在屏幕上显示的内容，比如，我在hello.txt中加入“Hello World！”。压缩data目录，然后将压缩文件data.zip加入Xcode的resource。（注意：此时加入的zip文件将出现在Targets下的“Link Binary With Libraries”下，编译时会出现一个警告，zip文件将不会被加入到.app中。所以你应该将data.zip移动到&#8221;Copy Bundle Resources&#8221;下）

2. ziptestViewController.h部分如下：
12345@interface ziptestViewController : UIViewController &#123;
&#160; &#160; UILabel* _mytext;
&#125;

@property &#40;nonatomic,retain&#41; IBOutlet UILabel* _mytext;
3. 将ziptestViewController.m重命名为ziptestViewController.mm，部分代码如下：

4. 双击ziptestViewController.xib打开Interface Builder。添加一个Label。Control+点击File Owner拖动到新建的Label，选取_mytext。

5.然后加入header和library搜索路径。比如，我的Header Search Paths为：../../external/minizip++。然后按iphone项目使用静态库的最佳方法一文中介绍的方法加入ziptest项目。
6.在viewDidLoad下进入下列代码：
12345&#160; &#160; std::stringstream in;
&#160; &#160; zip::CReader reader;
&#160; &#160; NSString* zippath=&#91;&#91;&#91;NSBundle mainBundle&#93;resourcePath&#93;stringByAppendingPathComponent:@&#34;data.zip&#34;&#93;;
&#160; &#160; reader.openFile&#40;&#91;ziptestViewController getString:zippath&#93;,&#34;data/hello.txt&#34;,in&#41;;
&#160; &#160; _mytext.text = &#160;&#91;NSString stringWithCString:in.str&#40;&#41;.c_str&#40;&#41;&#93;;
6. 按Build and Go运行程序。
&#160;
minizip++中CReader类中用于解压的代码如下：
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970namespace zip
&#123;
&#160; &#160; 
&#160; &#160; void [...]]]></description>
			<content:encoded><![CDATA[<p>压缩和解压技术应用很广泛，比如游戏程序中的资源管理器可以使用压缩技术将许多文件打包，便于管理，也节约了空间。本文介绍使用minizip进行解压。由于可以使用zip工具比如winzip，betterzip等进行压缩，所以本文并未涉及压缩。</p>
<p>&nbsp;</p>
<p><span id="more-451"></span></p>
<h2>minizip++</h2>
<p>&nbsp;</p>
<p>我编写了一个简单的类，与minizip和zlib一起（实际上，Mac OSX中包括了zlib库，但其他平台不一定有zlib库，所以我将其包括在源码中），构成了minizip++。此类仅包含一个类zip::CReader，此类只包括一个函数openFile用于从zip文件中读取一个文件。</p>
<p>&nbsp;</p>
<h2>范例概述</h2>
<p>&nbsp;</p>
<p>本示例程序很简单，它从data.zip文件中提取data/hello.txt显示于屏幕上，有兴趣的话，你可以扩展此程序，从zip中提取图像然后显示出来。</p>
<p>&nbsp;</p>
<p>废话少说，下面介绍程序：</p>
<ul>
<li>1. 先建立一个View based Xcode项目ziptest，再创建一个目录data，在此目录下建立一个文本文件hello.txt，编辑此文本文件，加入你想在屏幕上显示的内容，比如，我在hello.txt中加入“Hello World！”。压缩data目录，然后将压缩文件data.zip加入Xcode的resource。（注意：此时加入的zip文件将出现在Targets下的“Link Binary With Libraries”下，编译时会出现一个警告，zip文件将不会被加入到.app中。所以你应该将data.zip移动到&#8221;Copy Bundle Resources&#8221;下）
</li>
<li>2. ziptestViewController.h部分如下：
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #a61390;">@interface</span> ziptestViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; UILabel<span style="color: #002200;">*</span> _mytext;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic,retain<span style="color: #002200;">&#41;</span> IBOutlet UILabel<span style="color: #002200;">*</span> _mytext;</div></td></tr></tbody></table></div>
<li>3. 将ziptestViewController.m重命名为ziptestViewController.mm，部分代码如下：
</li>
<li>4. 双击ziptestViewController.xib打开Interface Builder。添加一个Label。Control+点击File Owner拖动到新建的Label，选取_mytext。</li>
</li>
<li>5.然后加入header和library搜索路径。比如，我的Header Search Paths为：../../external/minizip++。然后按<a href="编程/iphone项目使用静态库的最佳方法">iphone项目使用静态库的最佳方法</a>一文中介绍的方法加入ziptest项目。</li>
<li>6.在viewDidLoad下进入下列代码：</li>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; std<span style="color: #002200;">::</span>stringstream <span style="color: #a61390;">in</span>;<br />
&nbsp; &nbsp; zip<span style="color: #002200;">::</span>CReader reader;<br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> zippath<span style="color: #002200;">=</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/"><span style="color: #400080;">NSBundle</span></a> mainBundle<span style="color: #002200;">&#93;</span>resourcePath<span style="color: #002200;">&#93;</span>stringByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;data.zip&quot;</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; reader.openFile<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>ziptestViewController getString<span style="color: #002200;">:</span>zippath<span style="color: #002200;">&#93;</span>,<span style="color: #bf1d1a;">&quot;data/hello.txt&quot;</span>,<span style="color: #a61390;">in</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; _mytext.text <span style="color: #002200;">=</span> &nbsp;<span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithCString<span style="color: #002200;">:</span><span style="color: #a61390;">in</span>.str<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>.c_str<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<li>6. 按Build and Go运行程序。</li>
<p>&nbsp;</p>
<p>minizip++中CReader类中用于解压的代码如下：</p>
<div class="codecolorer-container cpp mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">namespace</span> zip<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0000ff;">void</span> CReader<span style="color: #008080;">::</span><span style="color: #007788;">openFile</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> std<span style="color: #008080;">::</span><span style="color: #007788;">string</span><span style="color: #000040;">&amp;</span> zip,<span style="color: #0000ff;">const</span> std<span style="color: #008080;">::</span><span style="color: #007788;">string</span><span style="color: #000040;">&amp;</span> file,std<span style="color: #008080;">::</span><span style="color: #007788;">iostream</span><span style="color: #000040;">&amp;</span> in<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; unzFile uf<span style="color: #000080;">=</span><span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// open zip file</span><br />
<span style="color: #339900;">#ifdef USEWIN32IOAPI</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;zlib_filefunc_def ffunc<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fill_win32_filefunc<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>ffunc<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uf <span style="color: #000080;">=</span> unzOpen2<span style="color: #008000;">&#40;</span>zip.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,<span style="color: #000040;">&amp;</span>ffunc<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #339900;">#else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; uf <span style="color: #000080;">=</span> unzOpen<span style="color: #008000;">&#40;</span>zip.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
<span style="color: #339900;">#endif</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>uf<span style="color: #000080;">==</span><span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;No zip file found!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// find the file inside zip &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> unzLocateFile<span style="color: #008000;">&#40;</span>uf,file.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,0<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> UNZ_OK <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%s not found in zip<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>,file.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// file founded,extract it into the stream</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// open it </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> unzOpenCurrentFile<span style="color: #008000;">&#40;</span>uf<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> UNZ_OK <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// TODO: error handling</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;unzOpenCurrentFile error<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// get the file info</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">char</span> filename_inzip<span style="color: #008000;">&#91;</span>256<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">int</span> err<span style="color: #000080;">=</span>UNZ_OK<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; unz_file_info file_info<span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; err <span style="color: #000080;">=</span> unzGetCurrentFileInfo<span style="color: #008000;">&#40;</span>uf,<span style="color: #000040;">&amp;</span>file_info,filename_inzip,<span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>filename_inzip<span style="color: #008000;">&#41;</span>,<span style="color: #0000ff;">NULL</span>,0,<span style="color: #0000ff;">NULL</span>,0<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>err<span style="color: #000040;">!</span><span style="color: #000080;">=</span>UNZ_OK<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// TODO: error handling</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;error %d with zipfile in unzGetCurrentFileInfo<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>,err<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// read the file into stream</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> buf <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">malloc</span><span style="color: #008000;">&#40;</span>file_info.<span style="color: #007788;">uncompressed_size</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span> unzReadCurrentFile<span style="color: #008000;">&#40;</span>uf,buf,file_info.<span style="color: #007788;">uncompressed_size</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">0</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// TODO: error handling</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;error in unzReadCurrentFile!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">free</span><span style="color: #008000;">&#40;</span>buf<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// write to istream</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; in.<span style="color: #007788;">rdbuf</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>sputn<span style="color: #008000;">&#40;</span>buf,file_info.<span style="color: #007788;">uncompressed_size</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000dd;">free</span><span style="color: #008000;">&#40;</span>buf<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; unzCloseCurrentFile<span style="color: #008000;">&#40;</span>uf<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; unzClose<span style="color: #008000;">&#40;</span>uf<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<h2><strong>源码下载</strong></h2>
<p>&nbsp;</p>
<p><a href='http://www.iphone-geek.cn/wp-content/uploads/2009/12/ziptest.zip'>ziptest</a></p>
<p>&nbsp;</p>
<p>注意：编译时，你需要修改头文件路径或者按照我的路径解压源代码。我的路径如下：</p>
<p>&nbsp;</p>
<p><quoteblock><br />
root<br />
  |&#8212;&#8212; external<br />
                 |&#8212;&#8212;&#8212;&#8211; minizip++</p>
<p>  |&#8212;&#8212; test<br />
                 |&#8212;&#8212;&#8212;&#8211; ziptest<br />
</quoteblock></p>
<p>&nbsp;</p>
<p><a href='http://www.iphone-geek.cn/wp-content/uploads/2009/12/minizip++.zip'>minizip++</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b7%a8%e5%b9%b3%e5%8f%b0%e4%bb%a3%e7%a0%81%e5%88%86%e4%ba%ab%e4%b9%8b%e5%85%ad-%e4%bd%bf%e7%94%a8minizip%e8%bf%9b%e8%a1%8c%e8%a7%a3%e5%8e%8b/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>开始学习iPhone编程之五 &#8211; Objective C / Cocoa / iPhone的内存管理</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%bc%80%e5%a7%8b%e5%ad%a6%e4%b9%a0iphone%e7%bc%96%e7%a8%8b%e4%b9%8b%e4%ba%94-objective-c-cocoa-iphone%e7%9a%84%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%bc%80%e5%a7%8b%e5%ad%a6%e4%b9%a0iphone%e7%bc%96%e7%a8%8b%e4%b9%8b%e4%ba%94-objective-c-cocoa-iphone%e7%9a%84%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86#comments</comments>
		<pubDate>Wed, 23 Dec 2009 05:11:27 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[内存管理]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=354</guid>
		<description><![CDATA[随着iPhone SDK的发布，iPhone/iPod Touch被售出数以百万计（作者注：这是一篇以前的文章，现在iPhone/iPod Touch的销售数量远大于此数）而且App Store广受欢迎，越来越多的开发者开始进行iPhone及Cocoa Touch的开发。SDK设计精良而且很容易入门，最大的障碍来自于Apple选择作为OSX和iPhone开发的独特语言（其前身为NextStep）：Object C。初看时，Object C非常丑陋而且与人们常用的基于C的语法（C, C++, ActionScript, JavaScript, Java, C#, GLSL等）并不相似。但一旦对其有所研究后，你会喜欢上它并明白其语法为何如此。
&#160;
大部分人初次接触Objective C/Cocoa开发时的最大困难是内存管理 &#8211; 当你最终理解了它是多么简单（尽管这可能需要通过几个项目）时，你就会明白这一切实际上是多么漂亮。实际上，我发现其非常实用，所以编写了一个C++类来实现类似功能(http://code.google.com/p/ofxmsaof/wiki/ofxObjCPointer).
&#160;

C/C++的方式
&#160;
对于传统C/C++开发，确定使用过后的对象清理的职责多多少少有那么些噩梦的意味。C/C++语言本身并未提供怎样进行此项工作方法，一切都取决于程序员本身个人的习惯和约定。
&#160;
想象一下程序员A编写了一段代码(类A)，此段代码创建叫做Data的对象并为其分配内存然后将此对象传递给程序员B，B将在他的代码（类B)中使用此对象。两个程序员使用同一个对象Data。到底是谁应该在不再使用对象Data后对其进行删除？
&#160;
如果类A只是创建和初始化Data并不再使用它，那么类B可以在使用完Data后安全地删除它。但是，怎样才能保证类A不再使用Data？如果在类B使用Data时类A仍然需要使用它，我们怎样才能知道何时删除它？如果类A在使用完Data后进行删除，类B有可能还需要使用，这会导致程序崩溃。如果类B在使用完后进行删除，同样如果类A还在使用将会引起崩溃。当然，如果类C也需要更新同一Data，那么情况会更复杂。
&#160;
有一些约定和模式可以处理这些情况，比如有下列形式的通讯：&#8221;等下，不要删除对象，我正在使用&#8221; 或者 &#8220;好，我使用完毕，你可以任意处置&#8220;。这实际上正好是开发引用计数的原因，这种技术是Objective C使用的主要内存管理技术。
&#160;
Objective C的方式
&#160;
Objective C 使用&#8217;引用计数&#8217;作为其主要内存管理技术(wikipedia.org/wiki/Reference_counting)。 每个对象都保存一份记录了它被“需要”的次数的内部计数器。系统保证当对象被需要时不会被删除，当不被需要时才被删除。这听上去有点象自动垃圾收集(即Java, AS3 wikipedia.org/wiki/Garbage_collection_(computer_science)的工作方式)，但实际上并不是如此。它与自动GC (Java, AS3 等)的主要区别在于，GC是一段单独的代码在后台定期运行检查是否对象被引用以及哪个对象不再被需要。然后所有未被使用的对象将被自动删除，程序员不需做任何特殊处理。而引用计数方法，程序员有责任通知他需要使用或完成使用某个对象，当对象不再被使用时，即引用计数为0时，它将立即被删除。（有关更多详情请参考以上wikipedia链接）。
&#160;
注意： Objective C 2.0 同样具有一个选项允许自动垃圾收集。但是，开发iPhone程序不能使用此选项，所以了解引用计数，对象所有权等仍然十分重要。
&#160;
对象拥有者
&#160;
理解对象拥有者的概念十分重要。在Objective C中， 一个对象的所有者是宣称“我需要此对象，不要删除它”的某人（或某段代码）。它可能是创建此对象的人（或代码）（比如上例中的类A）。或者它可能是接收并需要此对象的另一个人（或代码）（即上例中的类B）。一个对象可以具有不只一个所有者。 一个对象的所有者的数量就是引用计数。
&#160;
对象所有者有责任在使用完毕后通知对象。这样做后，他们将不再是对象的所有者，或者说对象的引用计数减一。当一个对象没有所有者时（即没人再需要时或引用计数为0），它将被删除。
&#160;
不作为对象的拥有者（临时使用）你仍然可以使用对象，但是要记住此对象可能已经（或者将）被删除。所以如果你希望长期使用一个对象，你应该成为对象的拥有者。如果你只打算临时使用对象（例如，在你的函数中，或者事件循环中 &#8211; 后面会介绍autorelease pool），那么你不需要成为拥有者。
&#160;
消息
&#160;
你可以传递给一个对象的主要消息（有关内存管理）是：
&#160;
alloc (即 [NSString alloc]): 此消息为对象分配了一个例程（本例中为NSString）。它同时将引用计数设为1。你是此对象的唯一拥有者。当使用完毕时，你必须释放此对象。（题外话：记住对新分配的对象调用init函数： [[NSString alloc] init] 或 [[NSString alloc] initWithFormat:] 。)
&#160;
new (例如： [NSString new]): 这是[[NSString [...]]]></description>
			<content:encoded><![CDATA[<p>随着iPhone SDK的发布，iPhone/iPod Touch被售出数以百万计（作者注：这是一篇以前的文章，现在iPhone/iPod Touch的销售数量远大于此数）而且App Store广受欢迎，越来越多的开发者开始进行iPhone及Cocoa Touch的开发。SDK设计精良而且很容易入门，最大的障碍来自于Apple选择作为OSX和iPhone开发的独特语言（其前身为NextStep）：Object C。初看时，Object C非常丑陋而且与人们常用的基于C的语法（C, C++, ActionScript, JavaScript, Java, C#, GLSL等）并不相似。但一旦对其有所研究后，你会喜欢上它并明白其语法为何如此。</p>
<p>&nbsp;</p>
<p>大部分人初次接触Objective C/Cocoa开发时的最大困难是内存管理 &#8211; 当你最终理解了它是多么简单（尽管这可能需要通过几个项目）时，你就会明白这一切实际上是多么漂亮。实际上，我发现其非常实用，所以编写了一个C++类来实现类似功能(<a title="http://code.google.com/p/ofxmsaof/wiki/ofxObjCPointer" href="http://code.google.com/p/ofxmsaof/wiki/ofxObjCPointer">http://code.google.com/p/ofxmsaof/wiki/ofxObjCPointer</a>).</p>
<p>&nbsp;</p>
<p><span id="more-354"></span></p>
<h2>C/C++的方式</h2>
<p>&nbsp;</p>
<p>对于传统C/C++开发，确定使用过后的对象清理的职责多多少少有那么些噩梦的意味。C/C++语言本身并未提供怎样进行此项工作方法，一切都取决于程序员本身个人的习惯和约定。</p>
<p>&nbsp;</p>
<p>想象一下程序员A编写了一段代码(类A)，此段代码创建叫做Data的对象并为其分配内存然后将此对象传递给程序员B，B将在他的代码（类B)中使用此对象。两个程序员使用同一个对象Data。到底是谁应该在不再使用对象Data后对其进行删除？</p>
<p>&nbsp;</p>
<p>如果类A只是创建和初始化Data并不再使用它，那么类B可以在使用完Data后安全地删除它。但是，怎样才能保证类A不再使用Data？如果在类B使用Data时类A仍然需要使用它，我们怎样才能知道何时删除它？如果类A在使用完Data后进行删除，类B有可能还需要使用，这会导致程序崩溃。如果类B在使用完后进行删除，同样如果类A还在使用将会引起崩溃。当然，如果类C也需要更新同一Data，那么情况会更复杂。</p>
<p>&nbsp;</p>
<p>有一些约定和模式可以处理这些情况，比如有下列形式的通讯：&#8221;<strong>等下，不要删除对象，我正在使用</strong>&#8221; 或者 &#8220;<strong>好，我使用完毕，你可以任意处置</strong>&#8220;。这实际上正好是开发引用计数的原因，这种技术是Objective C使用的主要内存管理技术。</p>
<p>&nbsp;</p>
<h2>Objective C的方式</h2>
<p>&nbsp;</p>
<p>Objective C 使用&#8217;引用计数&#8217;作为其主要内存管理技术(<a href="http://en.wikipedia.org/wiki/Reference_counting" target="_blank">wikipedia.org/wiki/Reference_counting</a>)。 每个对象都保存一份记录了它被“需要”的次数的内部计数器。系统保证当对象被需要时不会被删除，当不被需要时才被删除。这听上去有点象自动垃圾收集(即Java, AS3 <a href="http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29" target="_blank">wikipedia.org/wiki/Garbage_collection_(computer_science)</a>的工作方式)，但实际上并不是如此。它与自动GC (Java, AS3 等)的主要区别在于，GC是一段单独的代码在后台定期运行检查是否对象被引用以及哪个对象不再被需要。然后所有未被使用的对象将被自动删除，程序员不需做任何特殊处理。而引用计数方法，程序员有责任通知他需要使用或完成使用某个对象，当对象不再被使用时，即引用计数为0时，它将立即被删除。（有关更多详情请参考以上wikipedia链接）。</p>
<p>&nbsp;</p>
<p>注意： Objective C 2.0 同样具有一个选项允许自动垃圾收集。但是，开发iPhone程序不能使用此选项，所以了解引用计数，对象所有权等仍然十分重要。</p>
<p>&nbsp;</p>
<h2>对象拥有者</h2>
<p>&nbsp;</p>
<p>理解对象拥有者的概念十分重要。<strong>在Objective C中， 一个对象的所有者是宣称<strong>“我需要此对象，不要删除它”</strong>的某人（或某段代码）。它可能是创建此对象的人（或代码）（比如上例中的类A）。或者它可能是接收并需要此对象的另一个人（或代码）（即上例中的类B）。<strong>一个对象可以具有不只一个所有者。</strong> 一个对象的所有者的数量就是引用计数。</strong></p>
<p>&nbsp;</p>
<p><strong>对象所有者有责任在使用完毕后通知对象。这样做后，他们将不再是对象的所有者，或者说对象的引用计数减一。当一个对象没有所有者时（即没人再需要时或引用计数为0），它将被删除。</strong></p>
<p>&nbsp;</p>
<p>不作为对象的拥有者（临时使用）你仍然可以使用对象，但是要记住此对象可能已经（或者将）被删除。所以如果你希望长期使用一个对象，你应该成为对象的拥有者。如果你只打算临时使用对象（例如，在你的函数中，或者事件循环中 &#8211; 后面会介绍autorelease pool），那么你不需要成为拥有者。</p>
<p>&nbsp;</p>
<h2><strong>消息</strong></h2>
<p>&nbsp;</p>
<p>你可以传递给一个对象的主要消息（有关内存管理）是：</p>
<p>&nbsp;</p>
<p><strong>alloc</strong> (即 [NSString alloc]): 此消息为对象分配了一个例程（本例中为NSString）。它同时将引用计数设为1。你是此对象的唯一拥有者。当使用完毕时，你必须释放此对象。（题外话：记住对新分配的对象调用init函数： [[NSString alloc] init] 或 [[NSString alloc] initWithFormat:] 。)</p>
<p>&nbsp;</p>
<p><strong>new</strong> (例如： [NSString new]): 这是[[NSString alloc] init]的简写。</p>
<p>&nbsp;</p>
<p><strong>retain</strong> (例如：[aString retain]): 当你传递一个存在的对象（内存已经分配）而且你需要保持它时你需要调用此函数。这就好像在说：<strong>“我需要此对象，不要在我完成前删除它”</strong>。引用计数将加1，你成为了此对象的拥有者（与以前拥有它的拥有者一起）。完成时，你必须释放它。</p>
<p>&nbsp;</p>
<p><strong>release</strong> （例如 [aString release]）: 在你完成对象的使用后调用。你将不再拥有此对象，因此引用计数将减1。如果此时引用计数为0（即没有拥有者），那么对象将被自动删除，内存被释放，否则因为其他拥有者还在使用，对象将继续保存在内存中。这就好像在说<strong>“好了，我已经使用完此对象，如果没有人使用它，你可以删除它了”</strong>。如果你<strong>不是</strong>此对象的拥有者，你<strong>不应该</strong>调用此函数。如果你 <strong>是</strong>对象的拥有者，在你完成后，你<strong>必须</strong>调用它。</p>
<p>&nbsp;</p>
<p><strong>autorelease</strong> (例如： [aString autorelease])。它表示你只是暂时需要对象，并<strong>不会</strong>使你成为对象的拥有者。这好像在说<strong>&#8220;Ok，我现在需要对象，在我完成几件事前保留在内存中，然后你可以删除它。&#8221;</strong>。更多介绍请参见稍后的&#8217;autorelease pools&#8217;部分。</p>
<p>&nbsp;</p>
<p>所以当你在与Objective C指针/对象打交道时，重要的是要记住发送正确的消息。基本规则是：<strong>如果你拥有一个对象(分配（alloc）或保持 （retain）它)，那么你必须释放（release）它。如果你不拥有它 (通过便捷方式产生或别人分配），那么你就不要释放它。</strong></p>
<p>&nbsp;</p>
<h2><strong><strong>便捷方法</strong></strong></h2>
<p>&nbsp;</p>
<p>Cocoa下的许多类都具有所谓便捷方法。它们是用于直接分配和初始化对象的静态方法。你并不会成为返回对象的拥有者，它们将在autorelease pool （自动释放池）弹出时（通常在事件循环的结束处，但与你的程序相关）自动被删除。</p>
<p>&nbsp;</p>
<p>例如，显性地分配和初始化一个NSNumber的方法是：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">5</span>;</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>此方法创建一个NSNumber的新例程并通过&#8217;initWithFloat&#8217;方法使用参数5.0f进行初始化。</p>
<p>&nbsp;</p>
<p>aNumber的引用计数为1。你是aNumber的拥有者，所以你必须在使用完毕后释放它。</p>
<p>&nbsp;</p>
<p><strong>使用便捷方法：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>5.0f<span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>此方法同样创建一个NSNumber的新例程，通过&#8217;numberWithFloat&#8217;方法使用参数5.0f进行初始化。</p>
<p>&nbsp;</p>
<p>它同样具有引用计数1。<strong>但是你不是aNumber的拥有者所以不应该释放它。</strong>拥有者是NSNumber类，对象在当前作用域结束时被删除 &#8211; 由autorelease pool定义，详情稍后介绍 &#8211; 你不应该<strong>release（释放）</strong> 对象，但要记住对象将存在一段较长的时间。</p>
<p>&nbsp;</p>
<p>便捷方法通常具有与相应<em>init</em>函数一样的名字，但将<em>init </em>替换为对象类型的名字了，比如对于NSNumber: <em>initWithFloat -&gt; </em><em>numberWithFloat， initWithInt -&gt; numberWithInt。</em></p>
<p>&nbsp;</p>
<p><strong>一个NSString的例子：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>aString1 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Results are %i and %i&quot;</span>, int1, int2<span style="color: #002200;">&#93;</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// explicit allocation, you are the owner, you must release when you are done</span><br />
<br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>aString2 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Results are %i and %i&quot;</span>, int1, int2<span style="color: #002200;">&#93;</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// convenience method, you are not the owner, the object will be deleted when the autorelease pool is popped</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<h2><strong>自动释放池</strong></h2>
<p>&nbsp;</p>
<p>自动释放池是<em>NSAutoreleasePool</em>的一个例程，它定义了临时对象（将被自动释放的对象）的作用域。任何将被自动释放的对象（例如：你对其发送了<strong>autorelease</strong>消息的对象或者使用便捷方法创建的对象）都会被加入当前autorelease pool（自动释放池）中。当autorelease pool被弹出（释放）时，所有加入其中的对象也将被自动释放。这是管理临时对象自动释放的一种简单方法。</p>
<p>&nbsp;</p>
<p>例如，你希望创建几个对象用于临时计算，所以并不需要保持所有定义的局部变量以致在函数结束时需要为它们调用<strong>release</strong>， 你可以在创建时使用<strong>autorelease</strong> (或便捷方法)，它们将在下一次自动释放池弹出时自动被释放。注意：这样的做法有一个缺点，我将在<strong>便捷和显性方式的比较</strong>部分中讨论。</p>
<p>&nbsp;</p>
<p>Autorelease pool可以嵌套，这种情况下自动释放对象将被加入最近创建的autorelease pool中（释放池以后进先出堆栈的方式堆放）。</p>
<p>&nbsp;</p>
<p>示例在<strong>自动释放，便捷与显性方式比较</strong>一节中。</p>
<p>&nbsp;</p>
<h2><strong>数组，字典等</strong></h2>
<p>&nbsp;</p>
<p>数组，字典等通常保存加入其中的任何对象。（当使用第三方集合型对象时，请检查其文档看是否对象被保存）。这意味着这些集合是对象的拥有者，你在添加对象前不需要保持。</p>
<p>&nbsp;</p>
<p><strong>示例</strong></p>
<p>&nbsp;</p>
<p>下列代码将产生内存泄漏：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addNumberToArray<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat<br />
<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// reference count is now 1, you are the owner</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>anArray addObject<span style="color: #002200;">:</span> aNumber<span style="color: #002200;">&#93;</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// reference count is now 2, the array is also an owner as well as you.</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>如果你在数组之外的其他地方不需要用到对象，那么你必须在添加对象后进行释放。下面的代码是正确的：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> addNumberToArray<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// reference count is now 1, you are the owner</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>anArray addObject<span style="color: #002200;">:</span> aNumber<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// reference count is now 2, the array is also an owner as well as you.</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>aNumber release<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// reference count is now 1, you are not the owner anymore</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>现在，当数组被释放时，或者从数组中移除对象时，引用计数将减一，因为数组不再是对象的拥有者，所以对象将被删除。</p>
<p>&nbsp;</p>
<p>当然，另一种方法也是安全的：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> addNumberToArray<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// reference count is now 1, NSNumber is the owner, you are not</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>anArray addObject<span style="color: #002200;">:</span> aNumber<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// reference count is now 2, the array is also an owner as well as NSNumber.</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>现在当autorelease pool弹出时，NSNumber失去其所有权，引用计数降为一（只有数组是对象的拥有者了）。当数组被释放时，或者当对象被从数组中移除时，引用计数降为0，对象将被删除。</p>
<p>&nbsp;</p>
<p>你可能会想哪个才是最好的方法？ 方法一（显性地使用alloc和release)，或者方法二？(便捷方法)。在OSX中，我通常喜欢方法二，因为它看上去更简单而且需要更少的代码。功能上看上去是一样的，但实际上是不同的。实际上使用方法一是更好的方法（特别是为iPhone开发时），或者当你拥有自己的autorelease pool时，方法二更好。下面有详细说明。</p>
<p>&nbsp;</p>
<h2><strong>自动释放，便捷方式与显性方式比较</strong></h2>
<p>&nbsp;</p>
<p>你可能想知道到底下面两种方法有什么不同，或者说各有什么好处：</p>
<p>&nbsp;</p>
<p><strong>显性方式：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> doStuff<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
<span style="color: #11740a; font-style: italic;">/// ... do a bunch of stuff with aNumber...</span><br />
...<br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>aNumber release<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// release aNumber</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p><strong>自动释放方式：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> doStuff<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>;<span style="color: #11740a; font-style: italic;">// refcount is 1, you are not ownder, will be automatically release</span><br />
<span style="color: #11740a; font-style: italic;">/// ... do a bunch of stuff with aNumber...</span><br />
...<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>使用显性方式，aNumber在doStuf结束处立即被清除，内存被释放。</p>
<p>&nbsp;</p>
<p>而自动释放方式时，aNumber将在autorelease pool弹出时被释放，通常发生在事件循环的结束处。所以如果你在事件循环中创建了许多自动释放对象，它们都将被加入池中，可能会用完内存。在上例中可能还不是很清楚，我再给出一个例子：</p>
<p>&nbsp;</p>
<p><strong>显性方式：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> doStuff<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i<span style="color: #002200;">&amp;</span>lt;<span style="color: #2400d9;">100</span>; i<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">/// ... do a bunch of stuff with aNumber...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #002200;">&#91;</span>aNumber release<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// release aNumber</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#125;</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p><strong>自动释放方式：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> doStuff<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">float</span><span style="color: #002200;">&#41;</span>aFloat <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i<span style="color: #002200;">&amp;</span>lt;<span style="color: #2400d9;">100</span>; i<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>aFloat<span style="color: #002200;">&#93;</span>;<span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">/// ... do a bunch of stuff with aNumber...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: #002200;">&#125;</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>现在你可以看到，在第一个例子中，内存中不会超过一个NSNumber（NSNumber在开始处被分配，并在循环结束时被清除）。而在第二个例子中，每个循环都会创建一个新的NSNumber，而旧NSNumber仍处于内存中等待autorelease pool被释放。在桌面系统中，由于拥有内存大，你可以有更奢侈的选择，但在一个像iPhone这类内存有限的平台，更为重要的是保证对象在不在被需要时尽快删除。</p>
<p>&nbsp;</p>
<p>当然，另一个选择是创建你自己的autorelease pool，这在你使用了大量临时对象而你又不想麻烦分别释放它们时特别有用。看下下面代码：</p>
<p>&nbsp;</p>
<p><strong>显性方式：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> doStuff <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i<span style="color: #002200;">&amp;</span>lt;<span style="color: #2400d9;">100</span>; i<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber1 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>1<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber2 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>2<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber3 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>3<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber4 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>4<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber5 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>5<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber6 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> alloc<span style="color: #002200;">&#93;</span> initWithFloat<span style="color: #002200;">:</span>6<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are owner</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #11740a; font-style: italic;">// ... do a bunch of stuff with all objects above.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;...<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #11740a; font-style: italic;">// release all objects</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>aNumber1 release<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>aNumber2 release<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>aNumber3 release<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>aNumber4 release<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>aNumber5 release<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>aNumber6 release<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; <span style="color: #002200;">&#125;</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p><strong>自动释放方式：</strong></p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> doStuff <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i<span style="color: #002200;">&amp;</span>lt;<span style="color: #2400d9;">100</span>; i<span style="color: #002200;">++</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/"><span style="color: #400080;">NSAutoreleasePool</span></a> <span style="color: #002200;">*</span>pool <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/"><span style="color: #400080;">NSAutoreleasePool</span></a> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// create your own little autorelease pool</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #11740a; font-style: italic;">// these objects get added to the autorelease pool you created above</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber1 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>1<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber2 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>2<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber3 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>3<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber4 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>4<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber5 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>5<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>aNumber6 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> numberWithFloat<span style="color: #002200;">:</span>6<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// refcount is 1, you are not owner, will be automatically released</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #11740a; font-style: italic;">// ... do a bunch of stuff with all objects above.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;...<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #002200;">&#91;</span>pool release<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// all objects added to this pool (the ones above) are released</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#125;</span><br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>在这种情况下，两段代码实际上是一样的。在第一个例子中，6个NSNumber在循环开始处被创建，在循环结束时被显性释放（你拥有这些对象）。内存中不会超过6个NSNumber.</p>
<p>&nbsp;</p>
<p>在第二个例子中，你不会拥有任何NSNumber，但通过创建你自己的autorelease pool，你可以控制它们的生存期。因为你在循环中创建及释放autorelease pool，NSNumber仅存在于循环内，所以内存中也不会超过6个NSNumber。如果你不创建autorelease pool，那么在循环结束时，你会有6个NSNumber等待删除，在函数结束时将会有6&#215;100=600个NSNumber存在于内存中。与在其他函数中创建的自动释放对象一起，你可能会拥有大量未用的对象等待释放（所以不会引起内存泄漏），<strong>但是</strong>如果你没有及时释放，可能会到达内存上限。</p>
<p>&nbsp;</p>
<h2><strong>总结</strong></h2>
<p>&nbsp;</p>
<p>拥有一个对象表示你显性地宣称你需要它（通过使用<strong>alloc</strong>，<strong>new</strong>或者 <strong>retain</strong>)。</p>
<p>&nbsp;</p>
<p>如果你拥有一个对象，你必须显性地宣称你已经使用完毕（通过使用<strong>release</strong>)。</p>
<p>&nbsp;</p>
<p>如果你<strong>不是</strong>对象的拥有者（即你使用autorelease，或通过便捷方法，或它通过函数参数或返回值传递），那么<strong>不要</strong>释放对象。</p>
<p>&nbsp;</p>
<p>只有在你长期需要一个对象时，才保存（retain）它。如果你只在一个函数中需要它，你可以安全地不用拥有它。</p>
<p>&nbsp;</p>
<p>数组，字典等拥有加入其中对象的拥有者（调用retain），所以你在添加时<strong>不要</strong>显性保存。如果你在添加对象到集合前就拥有对象并且在集合之外不需要它，那么你必须在添加它到集合之后释放它。</p>
<p>&nbsp;</p>
<p>如果你需要使用大量临时对象（自动释放/使用便捷方法），为避免临时内存过大，应考虑使用临时autorelease pool。在iPhone中如果到达内存上限，程序将退出 &#8211; 尽管占用的内存不再需要时将会在autorelease pool中等待释放，但你仍然要有效地定期分配和释放内存。</p>
<p>&nbsp;</p>
<p>更详细的信息，请参考官方内存管理文档。<br />
<a href="http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html" target="_blank">developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html</a></p>
<p>&nbsp;</p>
<h5><strong><strong>原文见：<a href="http://memo.tv/memory_management_with_objective_c_cocoa_iphone">Memory Management with Objective C / Cocoa / iPhone</a></strong></strong></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e5%bc%80%e5%a7%8b%e5%ad%a6%e4%b9%a0iphone%e7%bc%96%e7%a8%8b%e4%b9%8b%e4%ba%94-objective-c-cocoa-iphone%e7%9a%84%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone项目使用静态库的最佳方法</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e9%a1%b9%e7%9b%ae%e4%bd%bf%e7%94%a8%e9%9d%99%e6%80%81%e5%ba%93%e7%9a%84%e6%9c%80%e4%bd%b3%e6%96%b9%e6%b3%95</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e9%a1%b9%e7%9b%ae%e4%bd%bf%e7%94%a8%e9%9d%99%e6%80%81%e5%ba%93%e7%9a%84%e6%9c%80%e4%bd%b3%e6%96%b9%e6%b3%95#comments</comments>
		<pubDate>Tue, 22 Dec 2009 05:20:40 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=369</guid>
		<description><![CDATA[由于Apple禁止在iPhone中使用外部框架或动态链接库，所以要重用代码（第三方库或自己的代码）只能选择如下方法：

直接将代码加入项目。这种方法有点笨。例如，你的一段代码被五个项目共享，如果你发现一个小bug，那么你需要更改五个地方。够麻烦吧？
使用静态库。这是我经常使用的方法。但Xcode并未为iPhone提供静态库的模板。有两种解决方法：



如果你的项目主要是使用Objective-C（C/C++也可使用，只要做些简单修改），那么你可使用现成的Xcode模板。
通过Mac OS X栏下的Static Library中的BSD Static Library建立一个静态库。但要用于iPhone项目，还需做些修改（需要将项目的Base SDK改为iPhone）。

&#160;


&#160;
但怎样在项目中链接静态库呢？如果你熟悉Xcode，那么你可跳过此段。很简单：

指定静态库的头文件路径Head Search Paths。


添加静态库到Xcode项目中。




&#160;
就这么简单。但是且慢，万事大吉了吗？如果你要修改你的静态库呢？你需要从Find中找到你的静态库项目，打开它修改。有点麻烦，不能像Visual Studio一样将相关项目包括在应用项目中吗？答案是：可以，虽然还是没有Visual Studio中的工作空间好用。但你可以从Xcode中直接打开相关的静态库。方法是使用Xcode的Cross-Project Reference(跨项目参考)。

将静态库的Xcode项目加入到当前项目。


右击Targets下本项目，添加到静态库项目的关联。


在项目下，扩展静态库项目，拖动xxxx.a到Targets下的Link Binary With Libraries。



&#160;
这样你就可以从当前项目下，双击静态库的项目来打开和修改静态库的代码了。
]]></description>
			<content:encoded><![CDATA[<p>由于Apple禁止在iPhone中使用外部框架或动态链接库，所以要重用代码（第三方库或自己的代码）只能选择如下方法：</p>
<ol>
<li>直接将代码加入项目。这种方法有点笨。例如，你的一段代码被五个项目共享，如果你发现一个小bug，那么你需要更改五个地方。够麻烦吧？</li>
<li>使用静态库。这是我经常使用的方法。但Xcode并未为iPhone提供静态库的模板。有两种解决方法：</li>
</ol>
<p><span id="more-369"></span></p>
<ul>
<li>如果你的项目主要是使用Objective-C（C/C++也可使用，只要做些简单修改），那么你可使用现成的<a href="http://www.iphone-geek.cn/%E7%BC%96%E7%A8%8B/iphone%E9%9D%99%E6%80%81%E5%BA%93%E9%A1%B9%E7%9B%AE%E6%A8%A1%E6%9D%BF">Xcode模板</a>。</li>
<li>通过Mac OS X栏下的Static Library中的BSD Static Library建立一个静态库。但要用于iPhone项目，还需做些修改（需要将项目的Base SDK改为iPhone）。</li>
</ul>
<p>&nbsp;</p>
<p style="text-align: center;"><a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/1.jpg"><img class="size-full wp-image-501 aligncenter" title="1" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/1.jpg" alt="1" width="480" height="354" /></a></p>
<p style="text-align: center;"><img title="2" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/2.jpg" alt="2" width="519" height="490" /></p>
<p>&nbsp;</p>
<p>但怎样在项目中链接静态库呢？如果你熟悉Xcode，那么你可跳过此段。很简单：</p>
<ol>
<li>指定静态库的头文件路径Head Search Paths。<br />
<a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/2.jpg"></a></li>
<p style="text-align: center;"><img title="3" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/3.jpg" alt="3" width="519" height="490" /></p>
<li>添加静态库到Xcode项目中。<br />
<a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/3.jpg"></a><a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/4.jpg"></a></li>
<p style="text-align: center;"><img class="alignnone size-full wp-image-504" title="4" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/4.jpg" alt="4" width="383" height="354" /></p>
<p style="text-align: center;">
</ol>
<p>&nbsp;</p>
<p>就这么简单。但是且慢，万事大吉了吗？如果你要修改你的静态库呢？你需要从Find中找到你的静态库项目，打开它修改。有点麻烦，不能像Visual Studio一样将相关项目包括在应用项目中吗？答案是：可以，虽然还是没有Visual Studio中的工作空间好用。但你可以从Xcode中直接打开相关的静态库。方法是使用Xcode的Cross-Project Reference(跨项目参考)。</p>
<ol>
<li>将静态库的Xcode项目加入到当前项目。<br />
<a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/5.jpg"></a></li>
<p style="text-align: center;"><img class="alignnone size-full wp-image-505" title="5" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/5.jpg" alt="5" width="298" height="383" /></p>
<li>右击Targets下本项目，添加到静态库项目的关联。<br />
<a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/6.jpg"></a></li>
<p style="text-align: center;"><img class="alignnone size-full wp-image-506" title="6" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/6.jpg" alt="6" width="519" height="490" /></p>
<li>在项目下，扩展静态库项目，拖动xxxx.a到Targets下的Link Binary With Libraries。<br />
<a href="http://www.iphone-geek.cn/wp-content/uploads/2009/12/7.jpg"></a></li>
<p style="text-align: center;"><img class="alignnone size-full wp-image-507" title="7" src="http://www.iphone-geek.cn/wp-content/uploads/2009/12/7.jpg" alt="7" width="242" height="418" /></p>
</ol>
<p>&nbsp;</p>
<p>这样你就可以从当前项目下，双击静态库的项目来打开和修改静态库的代码了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/iphone%e9%a1%b9%e7%9b%ae%e4%bd%bf%e7%94%a8%e9%9d%99%e6%80%81%e5%ba%93%e7%9a%84%e6%9c%80%e4%bd%b3%e6%96%b9%e6%b3%95/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
