Start Developing iOS Apps Today系列(十)

Start Developing iOS Apps Today系列之應用程序


10、編寫自定類


      開發 iOS 應用程序時,不少狀況下都須要編寫自定類。當您須要將自定行爲與數據打包在一塊兒時,自定類很是有用。在自定類中,能夠定義您本身的行爲來儲存、操控和顯示數據。 html

      例如,iOS 的「時鐘」應用程序中的「世界時鐘」標籤。比起標準表格視圖單元格,此表格視圖中的單元格須要顯示更多內容。這是實現子類的絕好機會,能夠擴展UITableViewCell的行爲,從而在給定的表格視圖單元格中顯示更多自定數據。若是要設計此自定類,您可能要爲標籤添加 Outlet,使信息前顯示小時數;還要添加圖像視圖,使單元格的右側顯示自定時鐘。 ios

image: ../Art/custom_class_2x.png

      本章會告訴您須要瞭解哪些 Objective-C 語法和類結構,才能實現 ToDoList 應用程序的行爲。還討論了XYZToDoItem的設計,該自定類將表示待辦事項列表上的單個項目。在第三個教程中,您將真正實現該類,並將它添加到您的應用程序中。 api

聲明並實現類

      在 Objective-C 中,類的說明須要兩個不一樣的部分:接口和實現。接口準確指定了一個給定類型的對象,如何專用於其餘對象。換句話說,它定義了類的實例與外部世界之間的公共接口。這個實現包括的可執行代碼,涵蓋了接口中聲明的每一個方法。 app

      對象的設計,應當隱藏其內部實現的細節。在 Objective-C 中,接口和實現一般放在單獨的文件中,這樣您只須要將接口設定爲公共屬性。和 C 代碼同樣,您須要定義頭文件和源代碼文件,將公共聲明與代碼的實現細節分開。接口文件具備.h擴展名,實現文件具備.m擴展名。(您將在「教程:添加數據」中爲XYZToDoItem類真正建立這些文件;眼下咱們只需跟着文稿來,由於全部內容都將講到。) 學習

接口

      Objective-C 語法常常採用如下方式來聲明類接口: ui

  1. @interface XYZToDoItem : NSObject

  2. @end

      該示例聲明瞭名爲XYZToDoItem的類,它繼承自NSObject。 spa

      公共屬性和行爲在@interface聲明內部定義。在此示例中,除了超類外,沒有指定任何內容,因此XYZToDoItem實例惟一可用的行爲繼承自NSObject。全部對象都要有一個最基本的行爲,所以在默認狀況下,它們必須繼承自NSObject(或它的一個子類)。 .net

實現

      Objective-C 語法常常採用如下方式來聲明類實現: 設計

  1. #import "XYZToDoItem.h"

  2. @implementation XYZToDoItem

  3. @end

      若是您在類接口中聲明瞭任何方法,那麼須要在此文件中實現它們。 htm

儲存對象的數據的屬性

      考慮待辦事項須要保存的信息。您可能須要知道事項的名稱,建立時間,以及是否已經完成。在自定XYZToDoItem類中,此信息儲存在屬性中。

      這些屬性的聲明在接口文件 (XYZToDoItem.h) 內部。以下所示:

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property NSDate *creationDate;

  5. @end

      在此示例中,XYZToDoItem類聲明瞭三個公共屬性。這些屬性徹底可供公開訪問。在公開訪問的狀況下,其餘對象能夠同時讀取和更改這些屬性的值。

      您可能想要聲明某個屬性不能被更改(也就是說,只能讀取)。指明一個屬性是否只讀(相對於其餘屬性),須要在 Objective-C 的屬性聲明中包括屬性的特性。例如,若是您不想XYZToDoItem的建立日期被改變,可能須要將XYZToDoItem類接口更新爲這樣:

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property (readonly) NSDate *creationDate;

  5. @end

      屬性能夠是私有的或公共的。有時讓屬性私有是合理的選擇,這樣其餘類就不能查看或訪問它。例如,若是您想要跟蹤的標記是項目完成的日期屬性,而且不想讓其餘類訪問此信息,請將此屬性設爲私有,方法是將它放在實現文件 (XYZToDoItem.m) 頂部的類擴展中。

  1. #import "XYZToDoItem.h"

  2. @interface XYZToDoItem ()
  3. @property NSDate *completionDate;
  4. @end

  5. @implementation XYZToDoItem

  6. @end

      您可使用 getter 和 setter 來訪問屬性。getter 返回屬性的值,setter 更改屬性的值。訪問 getter 和 setter 的常見語法簡寫是 dot notation(點表達式)。對於具備讀寫訪問權限的屬性,您可使用點表達式來獲取和設定屬性的值。若是您有XYZToDoItem類的一個對象toDoItem,能夠執行如下操做:

  1. toDoItem.itemName = @"Buy milk"; //Sets the value of itemName
  2. NSString *selectedItemName = toDoItem.itemName; //Gets the value of itemName

方法用來定義對象的行爲

      方法用來定義對象能作些什麼。方法是您定義的一段代碼,用來執行類中的任務或子程序。它能夠訪問類中儲存的數據,並使用該信息來執行一些操做。

      例如,要讓待辦事項 (XYZToDoItem) 可以被標記爲已完成,您能夠將markAsCompleted方法添加到類接口。稍後,您將在類實現中實現該方法的行爲,正如「實現方法」中所述。

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property (readonly) NSDate *creationDate;
  5. - (void)markAsCompleted;

  6. @end

      方法名稱前面的減號 (-) 指示它是一個實例方法,能夠用該類的對象調用。減號將它與類方法區分開來,類方法用加號 (+) 來表示。類方法可經過類自己來調用。類方法的一個常見示例是類工廠方法,您已經在「處理 Foundation」中學習過。您也可使用類方法來訪問與類相關的一些共享信息。

      在聲明的開始,用圓括號括住void關鍵詞,表示方法不會返回值。這種狀況下,markAsCompleted方法沒有任何參數。「方法參數」中會講述有關參數的更多信息。

方法參數

    在聲明方法時加上參數,可在調用方法時傳遞一些信息。

    例如,您能夠根據以前的代碼片斷修改markAsCompleted方法,讓其帶單個參數,藉此肯定項目是否標記爲完成或未完成。用這種方式,您能夠切換項目的完成狀態,而不僅是將它設爲完成。

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property (readonly) NSDate *creationDate;
  5. - (void)markAsCompleted:(BOOL)isComplete;

  6. @end

    如今,您的方法採用了一個參數isComplete,其類型爲BOOL。

    經過名稱引用帶一個參數的方法時,冒號將做爲方法名稱的一部分,因此更新後的方法名稱是markAsCompleted:。若是方法有多個參數,那麼它會被分解,並插入參數名稱。若是要將另外一個參數添加到此方法,其聲明將會是這樣的:

  1. - (void)markAsCompleted:(BOOL)isComplete onDate:(NSDate *)date;

在這裏,方法的名稱寫爲markAsCompleted:onDate:。實現時會使用名稱isComplete和date(會將這些名稱看成變量),來訪問方法被調用時所提供的值。

實現方法

    方法實現使用大括號來包括相關代碼。方法的名稱必須與接口文件中的對應方法相同,而且參數和返回類型必須徹底匹配。

    這是添加到XYZToDoItem類接口的markAsCompleted:方法的簡單實現:

  1. @implementation XYZToDoItem
  2. - (void)markAsCompleted:(BOOL)isComplete {
  3.     self.completed = isComplete;
  4. }
  5. @end

    與屬性同樣,方法也能夠是私有的或公共的。公共方法在公共接口中聲明,所以能夠被其餘對象查看和調用。它們的相應實現存在於實現文件中,其餘對象看不到。 私有方法僅有一個實現,並與類相同,這意味着只能夠在類實現中調用它們。這是一個強大的機制,可將內部行爲添加到類而不容許其餘對象進行訪問。

    例如,假設您想要讓待辦事項的completionDate保持更新。當待辦事項被標記爲完成,就將completionDate設定爲當前日期。當它被標記爲未完成,就將completionDate設定爲nil,由於它還沒有完成。因爲更新待辦事項的completionDate是自包含任務,因此最好的作法是爲其編寫專屬方法。可是,應當肯定其餘對象不能調用此方法。不然,其餘對象能夠隨時將待辦事項的completionDate設定爲任何內容。所以,請將此方法設爲私有。

      如今,更新XYZToDoItem的實現來包括私有方法setCompletionDate,該方法將會在markAsCompleted:內部調用,以便在待辦事項被標記爲已完成或未完成時,更新待辦事項的completionDate。請注意,您不會添加任何內容到接口文件,由於不想其餘對象看到此方法。


  1. @implementation XYZToDoItem
  2. - (void)markAsCompleted:(BOOL)isComplete {
  3.     self.completed = isComplete;
  4.     [self setCompletionDate];
  5. }
  6. - (void)setCompletionDate {
  7.     if (self.completed) {
  8.         self.completionDate = [NSDate date];
  9.     } else {
  10.         self.completionDate = nil;
  11.     }
  12. }
  13. @end




      如今,您已經使用XYZToDoItem類定義了待辦事項列表的基本實現。XYZToDoItem以屬性的形式儲存自身相關的信息——名稱、建立日期和完成狀態,而且會使用方法定義行爲——被標記爲已完成或未完成。這是您在下一個教程中實現 ToDoList 應用程序所需的功能擴展。不過,您隨時能夠嘗試將本身的屬性和方法添加到類,將新的行爲集成到您的應用程序中。

相關文章
相關標籤/搜索