<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Xcode on Dapeng Zhang</title><link>https://zhangdapeng.dev/tags/xcode/</link><description>Recent content in Xcode on Dapeng Zhang</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 25 Jun 2025 10:26:19 +0000</lastBuildDate><atom:link href="https://zhangdapeng.dev/tags/xcode/index.xml" rel="self" type="application/rss+xml"/><item><title>Using Xcode Storyboards to Build Dynamic TableViews with Prototype Table View Cells</title><link>https://zhangdapeng.dev/p/using-xcode-storyboards-to-build-dynamic-tableviews-with-prototype-table-view-cells/</link><pubDate>Wed, 25 Jun 2025 10:26:19 +0000</pubDate><guid>https://zhangdapeng.dev/p/using-xcode-storyboards-to-build-dynamic-tableviews-with-prototype-table-view-cells/</guid><description>&lt;p&gt;最近在做IOS开发，坚决支持自己要使用storyboard，关于动态的实现cell还一直不太会，终于找到了一篇外国牛人的帖子。直接粘贴了。想看的下面有链接的。噢耶。&lt;/p&gt;
&lt;p&gt;Creating the Example Project&lt;/p&gt;
&lt;p&gt;Start Xcode and create a single view application. Name the project and class prefix TableViewStory.&lt;/p&gt;
&lt;p&gt;A review of the files in the project navigator panel will reveal that, as requested, Xcode has created a view controller subclass for us named TableViewStoryViewController. In addition, this view controller is represented within the Storyboard file, the content of which may be viewed by selecting the MainStoryboard.storyboard file.&lt;/p&gt;
&lt;p&gt;In order to fully understand the steps involved in creating a Storyboard based TableView application we will start with a clean slate by removing the view controller added for us by Xcode. Within the storyboard canvas, select the Table View Story View Controller item so that it is highlighted in blue and press the Delete key on the keyboard. Next, select and delete both the corresponding TableViewStoryViewController.m and TableViewStoryViewController.h files from the project navigator panel. In the resulting panel select the option to delete the files.&lt;/p&gt;
&lt;p&gt;At this point we have a template project consisting solely of a storyboard file and the standard app delegate code files and are ready to begin building a storyboard based iPhone application using the UITableView and UITableViewCell classes.&lt;/p&gt;
&lt;p&gt;Adding the TableView Controller to the Storyboard&lt;/p&gt;
&lt;p&gt;From the perspective of the user, the entry point into this application will be a table view containing a list of cars, with each table view cell containing the vehicle make, model and corresponding image. As such, we will need to add a Table View Controller instance to the storyboard file. Select the MainStoryboard.storyboard file so that the canvas appears in the center of the Xcode window. From within the Object Library panel (accessible via the View -&amp;gt; Utilities -&amp;gt; Show Object Library menu option) drag a Table View Controller object and drop it onto the storyboard canvas as illustrated in Figure 18 1:&lt;/p&gt;
&lt;p&gt;Within the storyboard we now have a table view controller instance. Within this instance is also a prototype table view cell that we will be able to configure to design the cells for our table. At the moment these are generic UITableViewCell and UITableViewController classes that do not give us much in the way of control within our application code. So that we can extend the functionality of these instances we need to declare them as being subclasses of UITableViewController and UITableViewCell respectively. Before doing so, however, we need to actually create those subclasses.&lt;/p&gt;
&lt;p&gt;Creating the UITableViewController and UITableViewCell Subclasses&lt;/p&gt;
&lt;p&gt;We will be declaring the Table View Controller instance within our storyboard as being a subclass of UITableViewController named CarTableViewController. At present, this subclass does not exist within our project so clearly we need to create it before proceeding. To achieve this, select the File -&amp;gt; New -&amp;gt; New File… menu option and in the resulting panel select the option to create a new UIViewController subclass. Click Next and on the subsequent screen, name the class CarTableViewController and change the Subclass of menu to UITableViewController. Make sure that the Targeted for iPad and With XIB for user interface options are both turned off and click Next followed by Create.&lt;/p&gt;
&lt;p&gt;Within the Table View Controller added to the storyboard in the previous section, Xcode also added a prototype table cell. Later in this chapter we will add two labels and an image view object to this cell. In order to extend this class it is necessary to, once again, create a subclass. Perform this step by selecting the File -&amp;gt; New -&amp;gt; New File…. menu option. Within the new file dialog select Objective-C class and click Next. On the following screen, name the new class CarTableViewCell, change the Subclass of menu to UITableViewCell and proceed with the class creation.&lt;/p&gt;
&lt;p&gt;Next, the items in the storyboard need to be configured to be instances of these subclasses. Begin by selecting the MainStoryboard.storyboard file and select the Navigation Controller scene so that it is highlighted in blue. Within the identity inspector panel (View -&amp;gt; Utilities -&amp;gt; Show Identity Inspector) use the Class drop down menu to change the class from UITableViewController to CarTableViewController as illustrated in Figure 18-2:&lt;/p&gt;
&lt;p&gt;Similarly, select the prototype table cell within the table view controller storyboard scene and change the class from UITableViewCell to the new CarTableViewCell subclass. With the appropriate subclasses created and associated with the objects in the storyboard, the next step is to design the prototype cell.&lt;/p&gt;
&lt;p&gt;Declaring the Cell Reuse Identifier&lt;/p&gt;
&lt;p&gt;Later in the chapter some code will be added to the project to replicate instances of the prototype table cell. This will require that the cell be assigned a reuse identifier. With the storyboard still visible in Xcode, select the prototype table cell and display the Attributes Inspector. Within the inspector, change the Identifier field to carTableCell:&lt;/p&gt;
&lt;p&gt;Designing a Storyboard UITableView Prototype Cell&lt;/p&gt;
&lt;p&gt;Table Views are made up of multiple cells, each of which is actually either an instance of the UITableViewCell class or a subclass thereof. A useful feature of storyboarding allows the developer to visually construct the user interface elements that are to appear in the table cells and then replicate that cell at runtime. For the purposes of this example each table cell needs to display an image view and two labels which, in turn, will be connected to outlets that we will later declare in the CarTableViewCell subclass. Much like Interface Builder, components may be dragged from the Object Library panel and dropped onto a scene within the storyboard. Note, however, that this is only possible when the storyboard view is zoomed in. With this in mind, verify that the storyboard is zoomed in using the controls in the bottom right hand corner of the canvas and then drag and drop two Labels and an Image View object onto the prototype table cell. Resize and position the items so that the cell layout resembles that illustrated in Figure 18-4, making sure to stretch the label objects so that they extend toward the right hand edge of the cell.&lt;/p&gt;
&lt;p&gt;Having configured the storyboard elements for the table view portion of the application it is time to begin modifying the table view and cell subclasses.&lt;/p&gt;
&lt;p&gt;Modifying the CarTableViewCell Class&lt;/p&gt;
&lt;p&gt;Within the storyboard file two labels and an image view were added to the prototype cell which, in turn, has been declared as an instance of our new CarTableViewCell class. In order to manipulate these user interface objects from within our code we need to declare three outlets and then connect those outlets to the objects in the storyboard scene. Begin, therefore, by selecting the CarTableViewCell.h file and adding the three outlet properties as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CarTableViewCell&lt;/span&gt; : &lt;span style="color:#a6e22e"&gt;UITableViewCell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@property&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;nonatomic&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;strong&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;IBOutlet&lt;/span&gt; UIImageView &lt;span style="color:#f92672"&gt;*&lt;/span&gt;carImage;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@property&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;nonatomic&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;strong&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;IBOutlet&lt;/span&gt; UILabel &lt;span style="color:#f92672"&gt;*&lt;/span&gt;makeLabel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@property&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;nonatomic&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;strong&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;IBOutlet&lt;/span&gt; UILabel &lt;span style="color:#f92672"&gt;*&lt;/span&gt;modelLabel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Having declared the properties, synthesize access within the CarTableViewCell.m implementation file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import &amp;#34;CarTableViewCell.h&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@implementation&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CarTableViewCell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@synthesize&lt;/span&gt; makeLabel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; _makeLabel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@synthesize&lt;/span&gt; modelLabel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; _modelLabel;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@synthesize&lt;/span&gt; carImage &lt;span style="color:#f92672"&gt;=&lt;/span&gt; _carImage;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the outlet properties declared the next step is to establish the connections to the user interface objects. Within the storyboard file Ctrl-click on the white background of the prototype table cell and drag the resulting blue line to the uppermost of the two labels as outlined in Figure 18-5:&lt;/p&gt;
&lt;p&gt;Upon releasing the pointer, select makeLabel from the resulting menu to establish the outlet connection:&lt;/p&gt;
&lt;p&gt;Repeat these steps to connect the modelLabel and carImage outlets to the second label and image view objects respectively.&lt;/p&gt;
&lt;p&gt;Creating the Table View Datasource&lt;/p&gt;
&lt;p&gt;Dynamic Table Views require a datasource to provide the data that will be displayed to the user within the cells. By default, Xcode has designated the CarTableViewController class as the datasource for the table view controller in the storyboard. It is within this class, therefore, that we can build a very simple data model for our application consisting of a number of arrays. The first step is to declare these as properties in the CarTableViewController.h file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CarTableViewController&lt;/span&gt; : &lt;span style="color:#a6e22e"&gt;UITableViewController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@property&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;nonatomic&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;strong&lt;/span&gt;) NSArray &lt;span style="color:#f92672"&gt;*&lt;/span&gt;carImages;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@property&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;nonatomic&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;strong&lt;/span&gt;) NSArray &lt;span style="color:#f92672"&gt;*&lt;/span&gt;carMakes;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@property&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;nonatomic&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;strong&lt;/span&gt;) NSArray &lt;span style="color:#f92672"&gt;*&lt;/span&gt;carModels;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the properties declared these need to be synthesized within the CarTableViewController.m file. In addition, the arrays need to be initialized with some data when the application has loaded, making the viewDidLoad: method an ideal location. Select the CarTableViewController.m file within the project navigator panel and modify it as outlined in the following code fragment. Since we will be working with CarTableViewCell instances within the code it is also necessary to import theCarTableViewCell.h file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import &amp;#34;CarTableViewController.h&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import “CarTableViewCell.h”
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@implementation&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CarTableViewController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@synthesize&lt;/span&gt; carMakes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; _carMakes; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@synthesize&lt;/span&gt; carModels &lt;span style="color:#f92672"&gt;=&lt;/span&gt; _carModels;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@synthesize&lt;/span&gt; carImages &lt;span style="color:#f92672"&gt;=&lt;/span&gt; _carImages;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;viewDidLoad&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [super viewDidLoad];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self.carMakes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [[NSArray alloc]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initWithObjects:&lt;span style="color:#e6db74"&gt;@&amp;#34;Chevy&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;BMW&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;Toyota&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;Volvo&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;Smart&amp;#34;&lt;/span&gt;, nil];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self.carModels &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [[NSArray alloc]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initWithObjects:&lt;span style="color:#e6db74"&gt;@&amp;#34;Volt&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;Mini&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;Venza&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;S60&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;Fortwo&amp;#34;&lt;/span&gt;, nil];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self.carImages &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [[NSArray alloc]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initWithObjects:&lt;span style="color:#e6db74"&gt;@&amp;#34;chevy_volt.jpg&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;mini_clubman.jpg&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;toyota_venza.jpg&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;volvo_s60.jpg&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;smart_fortwo.jpg&amp;#34;&lt;/span&gt;, nil];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For a class to act as the datasource for a table view controller a number of methods must be implemented. These methods will be called by the table view object in order to obtain both information about the table and also the table cell objects to display. When we created the CarTableViewController class we specified that it was to be a subclass of UITableViewController. As a result, Xcode created templates of these data source methods for us within the CarTableViewController.m file. To locate these template datasource methods, scroll down the file until the #pragma mark – Table view data source marker comes into view. The first template method, named numberOfSectionsInTableView: needs to return the number of sections in the table. For the purposes of this example we only need one section so will simply return a value of 1 (note also that the #warning line needs to be removed):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (NSInteger)&lt;span style="color:#a6e22e"&gt;numberOfSectionsInTableView:&lt;/span&gt;(UITableView &lt;span style="color:#f92672"&gt;*&lt;/span&gt;)tableView
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Return the number of sections.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The next method is required to return the number of rows to be displayed in the table. This is equivalent to the number of items in our carModels array so can be modified as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (NSInteger)&lt;span style="color:#a6e22e"&gt;tableView:&lt;/span&gt;(UITableView &lt;span style="color:#f92672"&gt;*&lt;/span&gt;)tableView &lt;span style="color:#a6e22e"&gt;numberOfRowsInSection:&lt;/span&gt;(NSInteger)section
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Return the number of rows in the section.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; [self.carModels count];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above code calls the count method on the carModels array object to obtain the number of items in the array and returns that value to the table view.&lt;/p&gt;
&lt;p&gt;The final datasource method that needs to be modified is cellForRowAtIndexPath:. Each time the table view controller needs a new cell to display it will call this method and pass through an index value indicating the row for which a cell object is required. It is the responsibility of this method to create a new instance of our CarTableViewCell class (unless an instance already exists for re-use) and extract the correct car make, model and image file name from the data arrays based on the index value passed through to the method. The code will then set those values on the appropriate outlets on the CarTableViewCell object. Begin by removing the template code from this method and then re-write the method so that as reads as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (UITableViewCell &lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;tableView:&lt;/span&gt;(UITableView &lt;span style="color:#f92672"&gt;*&lt;/span&gt;)tableView &lt;span style="color:#a6e22e"&gt;cellForRowAtIndexPath:&lt;/span&gt;(NSIndexPath &lt;span style="color:#f92672"&gt;*&lt;/span&gt;)indexPath
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; NSString &lt;span style="color:#f92672"&gt;*&lt;/span&gt;CellIdentifier &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;carTableCell&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CarTableViewCell &lt;span style="color:#f92672"&gt;*&lt;/span&gt;cell &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [tableView
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dequeueReusableCellWithIdentifier:CellIdentifier];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (cell &lt;span style="color:#f92672"&gt;==&lt;/span&gt; nil) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cell &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [[CarTableViewCell alloc]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initWithStyle:UITableViewCellStyleDefault 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reuseIdentifier:CellIdentifier];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Configure the cell...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cell.makeLabel.text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [self.carMakes 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; objectAtIndex: [indexPath row]];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cell.modelLabel.text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [self.carModels 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; objectAtIndex:[indexPath row]];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; UIImage &lt;span style="color:#f92672"&gt;*&lt;/span&gt;carPhoto &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [UIImage imageNamed: 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [self.carImages objectAtIndex: [indexPath row]]];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cell.carImage.image &lt;span style="color:#f92672"&gt;=&lt;/span&gt; carPhoto;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; cell;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Before proceeding with this tutorial we need to take some time to deconstruct this code and explain what is actually happening. The code begins by creating a string that represents the reuse identifier that was assigned to the CarTableViewCell class within the storyboard (in this instance the identifier was set to carTableCell):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; NSString &lt;span style="color:#f92672"&gt;*&lt;/span&gt;CellIdentifier &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;carTableCell&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, the following lines of code are executed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CarTableViewCell &lt;span style="color:#f92672"&gt;*&lt;/span&gt;cell &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (cell &lt;span style="color:#f92672"&gt;==&lt;/span&gt; nil) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cell &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [[CarTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code calls the dequeueReusableCellWithIdentifier: method of the table view object to find out if an existing cell is available for re-use as the new row. If no cell is available then a new instance of the CarTableViewCell class is created ready for use. Having either created a new cell, or obtained an existing reusable cell the code simply uses the outlets previously added to the CarTableViewCell class to set the labels with the car make and model. The code then creates a new UIImage object configured with the image of the current car and assigns it to the image view outlet. Finally, the method returns the cell object to the table view:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Configure the cell...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cell.makeLabel.text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [self.carMakes objectAtIndex: [indexPath row]];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cell.modelLabel.text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [self.carModels objectAtIndex:[indexPath row]];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;UIImage &lt;span style="color:#f92672"&gt;*&lt;/span&gt;carPhoto &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [UIImage imageNamed:[self.carImages objectAtIndex: [indexPath row]]];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cell.carImage.image &lt;span style="color:#f92672"&gt;=&lt;/span&gt; carPhoto;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; cell;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Downloading and Adding the Image Files&lt;/p&gt;
&lt;p&gt;Before a test run of the application can be performed the image files referenced in the code need to be added to the project. An archive containing the images may be downloaded from the following URL:&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://www.ebookfrenzy.com/code/carImages.zip" target="_blank" rel="noopener"
 &gt;http://www.ebookfrenzy.com/code/carImages.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once the file has been downloaded, unzip the files and then drag and drop them from a Finder window onto the Supporting Files category of the Xcode project navigator panel.&lt;/p&gt;
&lt;p&gt;Compiling and Running the Application&lt;/p&gt;
&lt;p&gt;Now that the storyboard work and code modifications are complete the final step in this chapter is to run the application by clicking on the Run button located in the Xcode toolbar. Once the code has compiled the application will launch and execute within an iOS Simulator session as illustrated in Figure 18-7.&lt;/p&gt;
&lt;p&gt;Clearly the table view has been populated with multiple instances of our prototype table view cell, each of which has been customized through outlets to display different car information and photos. The next step, which will be outlined in the next chapter entitled Implementing TableView Navigation using Xcode Storyboards will be to use the storyboard to add navigation capabilities to the application so that selecting a row from the table results in a detail scene appearing to the user.&lt;/p&gt;
&lt;p&gt;Summary&lt;/p&gt;
&lt;p&gt;The Storyboard feature of Xcode significantly eases the process of creating complex table view based interfaces within iPhone applications. Arguably the most significant feature is the ability to visually design the appearance of a table view cell and then have that cell automatically replicated at run time to display information to the user in table form.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;木有图片，我木有copy图片过来的，你们自己去源文章看吧，我这里就简单的描述一下，其实是跟自己自定义一个cell是一个样子的（使用xib文件），只是这里的话直接在storyboard里面了&lt;/p&gt;</description></item><item><title>Xcode升级到5之后，iPhone的iOS7模拟器的大小和mini一样大 又如何使用原来的模拟器</title><link>https://zhangdapeng.dev/p/xcode-sheng-ji-dao-5-zhi-hou-iphone-de-ios7-mo-ni-qi-de-da-xiao-he-mini-yi-yang-da-you-ru-he-shi-yong-yuan-lai-de-mo-ni-qi/</link><pubDate>Mon, 23 Jun 2025 16:26:46 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode-sheng-ji-dao-5-zhi-hou-iphone-de-ios7-mo-ni-qi-de-da-xiao-he-mini-yi-yang-da-you-ru-he-shi-yong-yuan-lai-de-mo-ni-qi/</guid><description>&lt;p&gt;最近由于iOS7的出现，为了跟上步调，这不xcode也出新的了，刚出来，创建了一个小的应用，测试的时候就遇到了模拟器的问题，这里我记录一下，希望对看到本帖的人大有帮助&lt;/p&gt;
&lt;p&gt;当我创建完应用，然后运行的&lt;/p&gt;
&lt;p&gt;是不是觉得特别像mini啊，可以使用快捷键改变大小的哦，Command+1,Command+2,Command+3试试就知道了，大小不一样。&lt;/p&gt;
&lt;p&gt;但是是不是无论如何也找不到原来的样式的模拟器了是不是，首先先去看看，自己的模拟器有木有ios6的如果没有请你安装&lt;/p&gt;
&lt;p&gt;将Deployment target中的7.0改为6.0或者是6.1&lt;/p&gt;
&lt;p&gt;然后你去运行一下看看&lt;/p&gt;
&lt;p&gt;你可以选择运行iOS6.1啦&lt;/p&gt;</description></item><item><title>XCode实用插件</title><link>https://zhangdapeng.dev/p/xcode-shi-yong-cha-jian/</link><pubDate>Mon, 23 Jun 2025 15:48:58 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode-shi-yong-cha-jian/</guid><description>&lt;p&gt;IOS开发会遇到很多的问题，但是如果有一些好的插件的话，应该可以解决很多的问题的，尤其是在项目中，有了一些简便的插件，能够解决很大的问题。&lt;/p&gt;
&lt;h3 id="全能搜索家codepilot-20"&gt;&lt;a class="link" href="#1" &gt;全能搜索家CodePilot 2.0&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;你要找的是文件？是文件夹？是代码？Never Mind，CMD+SHIFT+X调出CodePilot，输入任何你想到搜的东西吧！想搜 appFinishLaunchingWithOptions？忘记咋拼了？没关系强大的代码搜索能力，appflaun一样也可以找到！超级强大的正则 匹配，匹配任何你所想！&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="http://codepilot.cc" target="_blank" rel="noopener"
 &gt;http://codepilot.cc&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="vim控必备的xvim"&gt;&lt;a class="link" href="#2" &gt;Vim控必备的XVim&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;XVim是一个针对Xcode的Vim插件，能让开发者在不放弃任何xcode功能的前提下体验vim的功能。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="https://github.com/JugglerShu/XVim" target="_blank" rel="noopener"
 &gt;https://github.com/JugglerShu/XVim&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="youcompletemevim的插件"&gt;&lt;a class="link" href="#3" &gt;YouCompleteMe（vim的插件）&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;如果你比较喜欢用vim来写代码的话，这里有一个非常棒的vim插件——YouCompleteMe——当你在编写OC代码时，可以提升体验。 YouCompleteMe可以在Vim中添加代码自动补全功能，并且不需要你来按某个键来查看代码补全建议——针对OC、OC++、C++以及C该插件 可以自动补全建议。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="https://github.com/Valloric/YouCompleteMe" target="_blank" rel="noopener"
 &gt;https://github.com/Valloric/YouCompleteMe&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="xcode颜色显示插件colorsense"&gt;&lt;a class="link" href="#4" &gt;XCode颜色显示插件ColorSense&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;代码里的那些冷冰冰的颜色数值，到底时什么颜色？如果你经常遇到这个问题，每每不得不运行下模拟器去看看，那么这个插件绝对不容错过。更彪悍的是你甚至可以点击显示的颜色面板，直接通过系统的ColorPicker来自动生成对应颜色代码，再也不用做各种颜色代码转换了！&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="https://github.com/omz/ColorSense-for-Xcode" target="_blank" rel="noopener"
 &gt;https://github.com/omz/ColorSense-for-Xcode&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="大段文本利器hostringsense"&gt;&lt;a class="link" href="#5" &gt;大段文本利器HOStringSense&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;经常输入大段文本的时候，如果文本里面有各种换行和特殊字符，经常会让人很头疼，有了HOStringSense，再也不不用为这个问题犯愁了，顺便附送字数统计功能。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="https://github.com/holtwick/HOStringSense-for-Xcode" target="_blank" rel="noopener"
 &gt;https://github.com/holtwick/HOStringSense-for-Xcode&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="规范注释生成器vvdocumenter"&gt;&lt;a class="link" href="#6" &gt;规范注释生成器VVDocumenter&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;很多时候，为了快速开发，很多的技术文档都是能省则省，这个时候注释就变得异常重要，再配合Doxygen这种注释自动生成文档的，就完美了。但 是每次都要手动输入规范化的注释，着实也麻烦，但有了VVDocumenter，规范化的注释，主需要输入三个斜线“///”，就OK啦！ （VVDocumenter在Mac OSX 10.8.5和Xcode 4.6.3上进行开发，应该能支持所有Xcode 4版本，如果想支持Xcode 5，可以对plist文件稍作修改。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="https://github.com/onevcat/VVDocumenter-Xcode" target="_blank" rel="noopener"
 &gt;https://github.com/onevcat/VVDocumenter-Xcode&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="cocoapods-for-xcode"&gt;&lt;a class="link" href="#7" &gt;CocoaPods for Xcode&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;非常方便的Xcode pods插件。可以很方便的在Xcode通过pods安装各种objective-c第三方库，省去以前还要手动去跑pods命令行的麻烦；此外，还支持 通过cocoaDocs来安装库文档。唯一的遗憾是，它目前只支持Xcode5，4版本还用不了。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="https://github.com/kattrali/cocoapods-xcode-plugin" target="_blank" rel="noopener"
 &gt;https://github.com/kattrali/cocoapods-xcode-plugin&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="xcode语法高亮插件"&gt;&lt;a class="link" href="#8" &gt;Xcode语法高亮插件&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;以前用eclipse开发，自带的有语法高亮的效果。做ios开发也许久了，但是没发现一款语法高亮的插件，因为xcode自己的效果是仅在变量 或类名下面加了个虚线，平时看起代码来十分不舒服，最近果断为xcode写了一款语法高亮的插件，不过功能非常有限，没有eclipse的那么好用，也没 对对象的作用域区分，勉强能使用吧。和有需要的分享一下吧。&lt;/p&gt;
&lt;p&gt;下载附件，解压后放在：你的用户/Library/Application Support/Developer/Shared/Xcode/Plug-ins目录下，有的童鞋还没有Plug-ins这个目录吧，那就手动建一个， 然后把解压后的highlight-Plugin.xcplugin放进去，重启xcode即可。然后就能看到高亮的菜单了。&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="http://www.cocoachina.com/bbs/read.php?tid=150107" target="_blank" rel="noopener"
 &gt;http://www.cocoachina.com/bbs/read.php?tid=150107&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="ksimagenamed-xcode"&gt;&lt;a class="link" href="#9" &gt;KSImageNamed-Xcode&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;为项目中使用的UIImage的imageNamed提供文件名自动补全功能。使用[UIImage imageNamed:@&amp;ldquo;xxx&amp;rdquo;]时，该插件会扫描整个workspace中的图片文件。&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="https://github.com/ksuther/KSImageNamed-Xcode" target="_blank" rel="noopener"
 &gt;https://github.com/ksuther/KSImageNamed-Xcode&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="xcode-extend-plug-in"&gt;&lt;a class="link" href="#10" &gt;xcode-extend-plug-in&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;帮助你快速格式化代码、生成注释、复制一行等。&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="https://code.google.com/p/xcode-extend-plug-in/" target="_blank" rel="noopener"
 &gt;https://code.google.com/p/xcode-extend-plug-in/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="xcodecolors"&gt;&lt;a class="link" href="#11" &gt;XcodeColors&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;改变调试控制台颜色&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="https://github.com/robbiehanson/XcodeColors" target="_blank" rel="noopener"
 &gt;https://github.com/robbiehanson/XcodeColors&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="scxcodeminimap"&gt;&lt;a class="link" href="#12" &gt;SCXcodeMiniMap&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;一个Xcode插件，可以在当前的窗口内创建一个代码迷你地图，并在屏幕上高亮提示。&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="https://github.com/stefanceriu/SCXcodeMiniMap" target="_blank" rel="noopener"
 &gt;https://github.com/stefanceriu/SCXcodeMiniMap&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="lin本地化字符串"&gt;&lt;a class="link" href="#13" &gt;Lin本地化字符串&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;之前我们提到过一个开源的Mac基础工具SCStringsUtility，可以让你在一个清爽的界面编辑不同的语言，简单地输入/输出 NSLocalizedString数据。Lin是一款功能相近的Xcode插件，提供了一个非常不错的操作界面，并且为不同的语言提供了不同的区域。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class="link" href="https://github.com/questbeat/Lin" target="_blank" rel="noopener"
 &gt;https://github.com/questbeat/Lin&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="插件管理alcatraz"&gt;&lt;a class="link" href="#14" &gt;插件管理Alcatraz&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;Alcatraz是一个开源的Xcode 4包管理器，可以让你更便捷地发现、安装以及管理插件、模板和配色方案。只需要简单地点击或者勾选，不需要手工复制和粘贴。&lt;/p&gt;
&lt;p&gt;项目地址： &lt;a class="link" href="https://github.com/mneorr/Alcatraz" target="_blank" rel="noopener"
 &gt;https://github.com/mneorr/Alcatraz&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Xcode5中的storyboard</title><link>https://zhangdapeng.dev/p/xcode5-zhong-de-storyboard/</link><pubDate>Fri, 20 Jun 2025 14:34:02 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode5-zhong-de-storyboard/</guid><description>&lt;p&gt;Xcode5 试用版发布了， 对于iOS开发者而言，仁者见仁，智者见智。 于我来说， 我更关心的是 storyboard 框架是否突破了原有的禁锢。&lt;/p&gt;
&lt;p&gt;说来还有一段故事。我一向是推崇storyboard 框架的， 对于iOS 初学者，若想后浪推前浪，一定要善用storyboard 技术，因为它可以让你在UI实现上事半而功倍。 当Xcode4.2 所推出的storyboard 框架也有其先天的不足。 具体表现在，整个UI视图都容纳到一个storyboard 文件中， 当多人修改这个文件时，会造成凌乱， 无法merge。 从而，storyboard技术从一开始，就被贴上了一个“缺陷”的标签。 那就是，不适用团队协同开发。 可谓一丑遮百俊。&lt;/p&gt;
&lt;p&gt;也正是这个诟病， storyboard 框架推行起来，困难重重。 尤其是习惯了通过编码写UI的程序员，更是抵触。&lt;/p&gt;
&lt;p&gt;那么，这次Xcode5的发布， 是否对storyboard 框架有所改进呢？ 经过测试，果然没人失望，这正是我所期待的。&lt;/p&gt;
&lt;p&gt;我们可以做个小实验，以便快速了解storyboard 框架的改进。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;通过Xcode 4.2 或4.5 或4.6 创建一个工程， 在storybaord 文件上，添加一个UIScrollview ，并在UIScrollview 内添加一些常用控件，比如： UILabel、 UIButton 等。 保存。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;storyboard 文件，从本质上说，是一个 xib 文件， 更具体地说，是一个XML文件。&lt;/p&gt;
&lt;p&gt;选中这个storyboard Open As &amp;gt; Source Code&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;通过Xcode5 打开以上工程， 再打开这个storyboard文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;从提示文字可以看出， 当用Xcode5打开这个文件时，这个文件会自动升级， 而且是不可逆的。 这就是意味着， 这个文件结构将发生变化。 选中 “upgrade”， 继续.&lt;/p&gt;
&lt;p&gt;这时， 再通过Open As &amp;gt; Source Code， 查看这个storyboard 文件结构。 你会惊喜地发现，xcode5 下的storyboard 文件结构比Xcode4 下，规整了很多， 更为重要的是， 这个XML的代码量大大缩减。 Xcode5下的storyboard 代码值规整，完全可以让你轻松地直接编写xml。&lt;/p&gt;
&lt;p&gt;至此，可以说，Xcode4下的storyboard框架之良莠参半，在Xcode5下已达到可圈可点。 它解决了 xib 文件的merge 问题， 从而使得团队协同使用storyboard 框架成为可能。&lt;/p&gt;</description></item><item><title>在XCode工程中创建bundle文件</title><link>https://zhangdapeng.dev/p/zai-xcode-gong-cheng-zhong-chuang-jian-bundle-wen-jian/</link><pubDate>Fri, 20 Jun 2025 11:33:19 +0000</pubDate><guid>https://zhangdapeng.dev/p/zai-xcode-gong-cheng-zhong-chuang-jian-bundle-wen-jian/</guid><description>&lt;p&gt;关于文件资源的管理，我觉得一个不错的方法，那就是使用bundle。下面是引用一位大牛的，感觉操作和说的都不错。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;在ios开发中为了方便管理资源文件，可以使用bundle的方式来进行管理，类似于ArcGIS Runtime for iOS中的ArcGIS.bundle .&lt;/p&gt;
&lt;p&gt;切记目前iOS中只允许使用bundle管理资源文件和国际化信息，不支持代码的打包。&lt;/p&gt;
&lt;p&gt;在xcode3.2.5 中只能够创建setting bundle，会默认创建一些配置文件，在xcode中无法直接删除，这也许不是我们需要的。&lt;/p&gt;
&lt;p&gt;那么如何使用最简单的方法创建一个bundle呢?&lt;/p&gt;
&lt;p&gt;1 创建一个文件夹&lt;/p&gt;
&lt;p&gt;2 将该文件夹重命名为a.bundle&lt;/p&gt;
&lt;p&gt;3 将a.bundle拖入到xcode中即可&lt;/p&gt;
&lt;p&gt;bundle的本质就是一个文件夹。当然在iOS中还可以干很多事情，详细资料请参考：&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://developer.apple.com/library/ios/#documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW7" target="_blank" rel="noopener"
 &gt;链接&lt;/a&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;在项目中大家自己的可以借鉴一下，方便自己的项目的文件管理&lt;/p&gt;</description></item><item><title>XCode下的iOS单元测试 GHUnit</title><link>https://zhangdapeng.dev/p/xcode-xia-de-ios-dan-yuan-ce-shi-ghunit/</link><pubDate>Thu, 19 Jun 2025 10:24:13 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode-xia-de-ios-dan-yuan-ce-shi-ghunit/</guid><description>&lt;p&gt;关于GHUnit的使用，我是摘自一篇比较不错的文章，里面即讲到了Xcode本身自带的测试工具OCUnit，同时也介绍了GHUnit，看完后很是受益呀。&lt;/p&gt;
&lt;p&gt;XCode 内置了 OCUnit 单元测试框架，但目前最好用的测试框架应该是 GHUnit。通过 GHUnit + OCMock 组合，我们可以在 iOS 下进行较强大的单元测试功能。本文将演示如何在 XCode 4.2 下使用 OCUnit， GHUnit 和 OCMock 进行单元测试。&lt;/p&gt;
&lt;h3 id="ocunit"&gt;&lt;a class="link" href="#1" &gt;OCUnit&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;在 XCode 下新建一个 OCUnitProject 工程，选中 Include Unit Tests 选择框，&lt;/p&gt;
&lt;p&gt;OCUnit 框架则会为我们自动添加 Unit Test 框架代码：&lt;/p&gt;
&lt;p&gt;XCode 在 OCUnitProjectTests.m 中为我们自动生成了一个 Fail 的测试：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;testExample&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; STFail(&lt;span style="color:#e6db74"&gt;@&amp;#34;Unit tests are not implemented yet in OCUnitProjectTests&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;让我们来运行 Test，看看效果：&lt;/p&gt;
&lt;p&gt;从图中的红色下划线部分可以看出，测试没有通过，符合预期。我们只要像类 OCUnitProjectTests 一样编写继承自 SenTestCase 类的子类，在其中添加形式如：- (void) testXXX(); 的测试函数既可，注意必须是一个无参无返回类型且名称是以 test 为前缀的函数。&lt;/p&gt;
&lt;p&gt;OCUnit 的有点是官方支持，于 XCode 集成的比较好。&lt;/p&gt;
&lt;h3 id="ghunit"&gt;&lt;a class="link" href="#2" &gt;GHUnit&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;GHUnit 是一个开源的单元测试框架，具有可视化界面，功能亦相当强大。Mark 写了一篇 OCUnit vs GHUnit 的文章，有兴趣的童鞋可以看一看。OCMock 是由 Mulle Kybernetik 为 OS X 和 iOS 平台编写的遵循 mock object 理念的单元测试框架。&lt;/p&gt;
&lt;p&gt;下面来介绍如何配置 GHUnit 和 OCMock&lt;/p&gt;
&lt;p&gt;1，首先，创建一个名为 GHUnitProject 的单视图应用程序，注意：不要选中 Include Unit Tests 选择框。然后运行，应该出现白屏。&lt;/p&gt;
&lt;p&gt;2，添加新的 test target，选中左边的工程名，点击右侧的 Add Target，新增一个名为 Tests 的 Empty Application 应用程序，让其附属于 GHUnitProject注意：不要选中 Include Unit Tests 选择框。&lt;/p&gt;
&lt;p&gt;3，向 Tests 工程中（注意是 Tests 工程）添加 GHUnitIOS Framework。首先下载与 XCode 版本对应的 GHUnitIOS Framework。英文好的可以直接查看官方 iOS 版的安装文档：点此查看，跳过此第 3 节；否则请接着看。&lt;/p&gt;
&lt;p&gt;3.1，解压 GHUnitIOS 框架到 GHUnitProject 下，让 GHUnitIOS.framework 与 Tests 在同一目录下。&lt;/p&gt;
&lt;p&gt;3.2，回到 XCode，右击工程中的 Frameworks group，选中 Add Files to&amp;hellip;菜单，选取 GHUnitIOS.framework ，注意 targets 要选择 Tests。&lt;/p&gt;
&lt;p&gt;3.3，设置 Tests 的 Build Settings：在 Other Linker Flags 中增加两个 flag： -ObjC 和 -all_load。&lt;/p&gt;
&lt;p&gt;3.4，删除 Tests 工程中的 UTSAppDelegate.h 和 UTSAppDelegate.m 两个文件；&lt;/p&gt;
&lt;p&gt;3.5，修改 Tests 工程中的 main.m 为:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;

#import &amp;lt;GHUnitIOS/GHUnitIOSAppDelegate.h&amp;gt;

int main(int argc, char *argv[])
{
 @autoreleasepool {
 return UIApplicationMain(argc, argv, nil, NSStringFromClass([GHUnitIOSAppDelegate class]));
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3.6，选择编译目标 Tests&amp;gt;iPhone 5.0 Simulator，编译运行，应该能得到如下效果。目前我们还没有编写任何实际测试，所以列表为空。&lt;/p&gt;
&lt;p&gt;4，编写 GHUnit 测试。向 Tests 工程中添加名为 GHUnitSampleTest 的 Objective C class。其内容如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import &amp;lt;GHUnitIOS/GHUnit.h&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GHUnitSampleTest&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;GHTestCase&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#import &amp;#34;GHUnitSampleTest.h&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@implementation&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GHUnitSampleTest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;testStrings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; NSString &lt;span style="color:#f92672"&gt;*&lt;/span&gt;string1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;a string&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GHTestLog(&lt;span style="color:#e6db74"&gt;@&amp;#34;I can log to the GHUnit test console: %@&amp;#34;&lt;/span&gt;, string1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Assert string1 is not NULL, with no custom error description
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GHAssertNotNULL(string1, nil);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Assert equal objects, add custom error description
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; NSString &lt;span style="color:#f92672"&gt;*&lt;/span&gt;string2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;@&amp;#34;a string&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GHAssertEqualObjects(string1, string2, &lt;span style="color:#e6db74"&gt;@&amp;#34;A custom error message. string1 should be equal to: %@.&amp;#34;&lt;/span&gt;, string2);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后编译运行，点击 Run，效果如下：&lt;/p&gt;
&lt;p&gt;图中的 All 栏显示所以的测试，Failed 栏显示没有通过的测试。强大吧，GHUnit。你可以向 GHUnitSampleTest 添加新的测试，比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;)&lt;span style="color:#a6e22e"&gt;testSimpleFail&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GHAssertTrue(NO, nil);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们可以向 Tests 添加更多测试类，只要该类是继承自 GHTestCase，且其中的测试方法都是无参无返回值且方法名字是以 test 为前缀即可&lt;/p&gt;
&lt;p&gt;是不是有种感觉就是，以后再多的bug都不怕啦。哦也&lt;/p&gt;</description></item><item><title>Xcode 4 设置App版本号</title><link>https://zhangdapeng.dev/p/xcode-4-she-zhi-app-ban-ben-hao/</link><pubDate>Tue, 17 Jun 2025 17:20:42 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode-4-she-zhi-app-ban-ben-hao/</guid><description>&lt;p&gt;刚接触ios开发的童鞋应该会对于app版本号吗有些疑问，因为target不仅仅在summary中有版本号，同样在Info.plist等地方也有版本号码的地方，一头乱码，不知吗？其实xcode在summary中已经将app最基本的设置进行了全面的封装，其余的plist，build setting等地方会跟着summary设置的改变而改变。&lt;/p&gt;
&lt;p&gt;一个version，一个build，都是设置版本的地方，有什么区别呢？&lt;/p&gt;
&lt;p&gt;在ios中(Android等工程中也一样),有两种version，一种是 CFBundleVersion (&amp;ldquo;Bundle Version&amp;rdquo;)，也就是我们看到的version,另一种是CFBundleShortVersionString (&amp;ldquo;Bundle version string, short&amp;rdquo;)，也就是我们看到的Build。&lt;/p&gt;
&lt;p&gt;普通情况下，我们只使用version即可，设置为&amp;quot;1.0&amp;quot;, &amp;ldquo;1.1&amp;rdquo;, &amp;ldquo;2.0&amp;rdquo; , etc，但如果你要使用两个版本号时候，需要将build设置为1,2,3&amp;hellip;等递增的整数，有什么用呢？&lt;/p&gt;
&lt;p&gt;version我们可以通过AppStore、itunes或其它软件看到，是给用户看的，而build是我们在团队开发中内部只用的，只有我们自己可以看到。比如团队打算发布1.0版本的时候，会发布很多build版本供测试或QA团队进行测试，你发布了很多build，因为一直在修改着代码，因此当你收到一条bug信息时候，你怎么知道是那个build引起的问题呢，这时候build版本号的有点就可以体现出来了，不是吗。&lt;/p&gt;
&lt;p&gt;我这里有一段代码，可以在xcode编译时候自动增加build号码。&lt;/p&gt;
&lt;p&gt;先把 Info.plist 里的版本号改成某个数字，然后 Targets → your target → Build Phases → Run Script 的地方加上：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-objectivec" data-lang="objectivec"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;version&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;libexec&lt;span style="color:#f92672"&gt;/&lt;/span&gt;PlistBuddy &lt;span style="color:#f92672"&gt;-&lt;/span&gt;c &lt;span style="color:#e6db74"&gt;&amp;#34;Print CFBundleVersion&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;PRODUCT_SETTINGS_PATH&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;version&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;expr &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;version &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;usr&lt;span style="color:#f92672"&gt;/&lt;/span&gt;libexec&lt;span style="color:#f92672"&gt;/&lt;/span&gt;PlistBuddy &lt;span style="color:#f92672"&gt;-&lt;/span&gt;c &lt;span style="color:#e6db74"&gt;&amp;#34;Set :CFBundleVersion $version&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;PRODUCT_SETTINGS_PATH
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#/usr/libexec/PlistBuddy -c &amp;#34;Set :CFBundleShortVersionString $version&amp;#34; $PRODUCT_SETTINGS_PATH 这行代码会让version也自增，一般不需要
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参考：http://blog.csdn.net/shencaifeixia1/article/details/8221273#&lt;/p&gt;</description></item><item><title>更新证书错误Code Sign error: Provisioning profile 'XXXX' can't be found</title><link>https://zhangdapeng.dev/p/geng-xin-zheng-shu-cuo-wu-code-sign-error-provisioning-profile-xxxx-cant-be-found/</link><pubDate>Tue, 17 Jun 2025 17:20:08 +0000</pubDate><guid>https://zhangdapeng.dev/p/geng-xin-zheng-shu-cuo-wu-code-sign-error-provisioning-profile-xxxx-cant-be-found/</guid><description>&lt;p&gt;在Xcode中当你在更新了你得证书而再重新编译你的程序，真机调试一直会出现 Code Sign error: Provisioning profile ‘XXXX’ can&amp;rsquo;t be found是不是会另你很恼火。下面说说解决方法，让你很好的解决这个问题。&lt;/p&gt;
&lt;p&gt;1.关闭你的项目，找到项目文件XXXX.xcodeproj，在文件上点击右键，选择“显示包内容”（Show Package Contents）。会新打开一个Finder。注：其实XXXX.xcodeproj就是一个文件夹，这里新打开的一个Finder里面的三个文件就是该XXXX.xcodeproj文件夹里面的文件。&lt;/p&gt;
&lt;p&gt;2.在新打开的Finder中找到project.pbxproj，并且打开。在这之中找到你之前的证书的编码信息。我之前报的错误信息是&lt;/p&gt;
&lt;p&gt;Code Sign error: Provisioning profile &amp;lsquo;37D44E7F-0339-4277-9A82-C146A944CD46&amp;rsquo;，所以我用查找的方式找到了所有包括37D44E7F-0339-4277-9A82-C146A944CD46的行，并且删除。&lt;/p&gt;
&lt;p&gt;3.保存，重新启动你的项目，再编译。就OK了。&lt;/p&gt;
&lt;p&gt;参考：http://www.douban.com/note/131009422/&lt;/p&gt;</description></item><item><title>xcode "nib but the view outlet was not set." 错误</title><link>https://zhangdapeng.dev/p/xcode-nib-but-the-view-outlet-was-not-set-cuo-wu/</link><pubDate>Fri, 13 Jun 2025 14:44:51 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode-nib-but-the-view-outlet-was-not-set-cuo-wu/</guid><description>&lt;p&gt;xib 中, 没有对File&amp;rsquo;s Owner 的Outlets view 进行绑定, 导致在父视图中插入子视图时出错, 在IB中拖拽Files&amp;rsquo; Owner到view, 添加绑定后, 运行成功!&lt;br&gt;
总结一下创建视图和绑定的步骤:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;创建控制器. File-&amp;gt;New File-&amp;gt;Iphone OS-&amp;gt;Cocoa Touch Class-&amp;gt;UIViewController subclass;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建xib. File-&amp;gt;New File-&amp;gt;Iphone OS-&amp;gt;User Interface-&amp;gt;View XIB&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;绑定controller和view. 用Interface Builder打开xxx.xib, 点击Files&amp;rsquo; Owner, 在Identity Inspector里面的Class Identity, 选择Step 1创建的控制器类, 接着拖拽File&amp;rsquo;s Owner到View中, 选择Outlets-&amp;gt;view.先选中file&amp;rsquo;s owner(这个很重要)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>clang: error: unable to execute command: posix_spawn failed: Resource temporarily unavailable</title><link>https://zhangdapeng.dev/p/clang-error-unable-to-execute-command-posix-spawn-failed-resource-temporarily-unavailable/</link><pubDate>Thu, 12 Jun 2025 09:40:43 +0000</pubDate><guid>https://zhangdapeng.dev/p/clang-error-unable-to-execute-command-posix-spawn-failed-resource-temporarily-unavailable/</guid><description>&lt;p&gt;Xcode下创建一个项目，但是运行的时候出现了如下的错误：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;clang: error: unable to execute command: posix_spawn failed: Resource temporarily unavailable
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;clang: error: clang frontend command failed due to signal &lt;span style="color:#f92672"&gt;(&lt;/span&gt;use -v to see invocation&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;经过查找资料，有个说明是这样的，如下：&lt;/p&gt;
&lt;p&gt;you may be running into too-low limits on the number of concurrent processes allowed on the machine. Check:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sysctl kern.maxproc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sysctl kern.maxprocperuid
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can increase them with e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo sysctl -w kern.maxproc&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo sysctl -w kern.maxprocperuid&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But normally this shouldn&amp;rsquo;t be necessary if you&amp;rsquo;re building on 10.7 or higher. If you see this, check if some rogue program spawned hundreds of processes and kill them first.&lt;/p&gt;
&lt;p&gt;我按照上面的流程执行了操作：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;davidzhang@davidzhang:~/command$ sysctl kern.maxproc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kern.maxproc: &lt;span style="color:#ae81ff"&gt;1064&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;davidzhang@davidzhang:~/command$ sysctl kern.maxprocperuid
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kern.maxprocperuid: &lt;span style="color:#ae81ff"&gt;709&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;davidzhang@davidzhang:~/command$ sudo sysctl -w kern.maxproc&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Password:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kern.maxproc: &lt;span style="color:#ae81ff"&gt;1064&lt;/span&gt; -&amp;gt; &lt;span style="color:#ae81ff"&gt;2500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;davidzhang@davidzhang:~/command$ sudo sysctl -w kern.maxprocperuid&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kern.maxprocperuid: &lt;span style="color:#ae81ff"&gt;709&lt;/span&gt; -&amp;gt; &lt;span style="color:#ae81ff"&gt;2500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后运行我的项目的时候，问题就解决了&lt;/p&gt;
&lt;p&gt;查询参考资料:http://code.google.com/p/chromium/wiki/MacBuildInstructions&lt;/p&gt;</description></item><item><title>XCode帮助文档离线使用</title><link>https://zhangdapeng.dev/p/xcode-bang-zhu-wen-dang-li-xian-shi-yong/</link><pubDate>Tue, 10 Jun 2025 13:39:10 +0000</pubDate><guid>https://zhangdapeng.dev/p/xcode-bang-zhu-wen-dang-li-xian-shi-yong/</guid><description>&lt;p&gt;1.在线查看帮助文件：&lt;/p&gt;
&lt;p&gt;Xcode下查看帮助文件，菜单Help-Developer Documentation在右上角搜索框中即可检索，但速度很慢，在线查看。&lt;/p&gt;
&lt;p&gt;2.下载帮助文件到本地：&lt;/p&gt;
&lt;p&gt;要想下载帮助文件，菜单Xcode-preferences-Documentation 右键Get Info可以看到Feed URL找到.atom文件地址，用FF浏览器访问可以看到下载列表，用迅雷下载即可。&lt;/p&gt;
&lt;p&gt;atom链接如下，复制到浏览器地址栏即可见到下载列表（用IE浏览器好像不行）&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://developer.apple.com/rss/com.apple.adc.documentation.AppleiPhone4" target="_blank" rel="noopener"
 &gt;http://developer.apple.com/rss/com.apple.adc.documentation.AppleiPhone4&lt;/a&gt;_2.atom&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://developer.apple.com/rss/com.apple.adc.documentation.AppleSnowLeopard.atom" target="_blank" rel="noopener"
 &gt;http://developer.apple.com/rss/com.apple.adc.documentation.AppleSnowLeopard.atom&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://developer.apple.com/rss/com.apple.adc.documentation.AppleXcode3" target="_blank" rel="noopener"
 &gt;http://developer.apple.com/rss/com.apple.adc.documentation.AppleXcode3&lt;/a&gt;_2.atom&lt;/p&gt;
&lt;p&gt;也可直接用下面的链接下载&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleLegacy.CoreReference.xar" target="_blank" rel="noopener"
 &gt;http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleLegacy.CoreReference.xar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://devimages.apple.com/docsets/20101122/com.apple.ADC" target="_blank" rel="noopener"
 &gt;http://devimages.apple.com/docsets/20101122/com.apple.ADC&lt;/a&gt;_Reference_Library.DeveloperTools.xar&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleSnowLeopard.JavaReference.xar" target="_blank" rel="noopener"
 &gt;http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleSnowLeopard.JavaReference.xar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleSnowLeopard.CoreReference.Xcode4.xar" target="_blank" rel="noopener"
 &gt;http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleSnowLeopard.CoreReference.Xcode4.xar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleiOS4" target="_blank" rel="noopener"
 &gt;http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleiOS4&lt;/a&gt;_2.iOSLibrary.Xcode4.xar&lt;/p&gt;
&lt;p&gt;3.下载后，拷贝到Mac的/Developer/Documentations/Docset目录下，&lt;/p&gt;
&lt;p&gt;使用终端命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo xar -xf 下载的文件名.xar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将其解压，然后修复权限:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chown -R -P devdocs 解压后的文件名.docset
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;打开Xcode就可以离线浏览了。&lt;/p&gt;</description></item></channel></rss>