1. 程式人生 > >Objective-C:神在細節之中

Objective-C:神在細節之中

Objective-C 是 C 語言的擴充套件,增加了動態型別和麵對物件的特性。它被設計成具有易讀易用的,支援複雜的面向物件設計的程式語言。它是 Mac OS X 以及 iPhone 的主要開發語言。

Cocoa 是 Mac OS X 上主要的應用程式框架之一。它由一組 Objective-C 類組成,為快速開發出功能齊全的 Mac OS X 應用程式提供支援。

而在日常的程式設計中,我們除了要寫程式碼,還需要去閱讀別人的程式碼,熟悉過往的業務邏輯。不知,你可曾發過牢騷:這程式碼怎麼能這麼寫呢?有些時候我們的程式碼,也會被別人去讀,不知你可曾想過,當別人讀到你的程式碼的時候會作何評價。

誠然,“讓程式碼能夠工作”是做為開發者的頭等大事。但是,程式碼的可維護性卻是更加影響深遠的一件事情。你的程式碼既有可能在下一個版本中被修改,也極有可能被交給另外的同事去修改。畢竟我們寫程式碼,不止是在和機器溝通,而且也是在和人溝通——和其他的程式設計師溝通。大家都知道“學好普通話,走遍天下都不怕”,同樣的道理:寫出一手漂亮的程式碼,你和誰溝通都沒問題。

即使你的原始程式碼修改之後,其程式碼風格和可讀性仍會影響到可維護性和可擴充套件性。即使程式碼不復存在,你的風格和律條仍存活下來。

下面我們將圍繞一些基本的準則展開討論,目的是讓我們寫出一手漂亮的程式碼,更好的用程式碼與其他同事溝通,也為了提高我們程式碼的可維護性和可修改性,也是為了讓我們自己工作的地方有一個愉悅的程式碼環境。

(PS:當你真的按照這些看似偏執的規則去做的時候,你就真的能夠發現“偉大來自細節”,而且會受益匪淺。保劍鋒自磨礪出,梅花香自苦寒來。)

總則

1.Don’t repeat your self.

2.程式碼自注釋,依靠程式碼本身來表達你的設計意圖,不要依賴註釋。

3.單一指責,無論是類、函式、模組、包儘可能令其指責純淨且單一。

4.死程式不說謊,不要因為防止Crash寫奇葩的程式碼。程式Crash了,反而更容易查詢錯誤。

5.借用美國童子軍軍規:讓營地比你來時更乾淨。

格式

1.任意函式長度不得超過50行。

2.任意行程式碼不得超過80字元。可以在設定中設定超過80個字元的提醒。

3.在定義函式的行前留白一行

4.功能相近的程式碼要放在一起。

5.使用#pragma來切分不同功能區域的程式碼。

6.二元運算子和引數之間需要放置一個空格,一元運算子、強制型別轉換和引數之間不放置空格。關鍵字之後圓括號之前需要放置一個空格.

void *ptr = &value + 10 * 3;

NewType a = (NewType)b;

for (int i = 0; i < 10; i++) {

doCoolThings();

}

7.長的字面值應被拆分為多行。

NSArray *theShit = @[

@"Got some long string objects in here.",

[AndSomeModelObjects too],

@"Moar strings."

];

NSDictionary *keyedShit = @{

@"this.key": @"corresponds to this value",

@"otherKey": @"remoteData.payload",

@"some": @"more",

@"JSON": @"keys",

@"and": @"stuff",

};

命名

命名是程式設計中最基本的技能,我們給變數、函式、類、包等等命名。給他們以名字,讓他們有意義,既能表示他們到底是做什麼的,也能將其與其他變數區別開來。而通過,語言的發展史,我們也能夠看到“方便程式設計人員理解和使用”一直都是程式語言發展的動力之一,而命名則是其最最核心的環節。像人一樣娶一個好名字至關重要,“丁當”總比“狗蛋”來的好聽。

為什麼要命名?命名代表著抽象,我們使用名字將一些沒必要關係的細節隱去,減少我們自己的記憶成本,也更加方便我們理解。用過C語言的人都知道,一個變數名最終會轉化成類似於~~~0x11111111~~~之類的地址,相比去理解和記憶這些地址,用一個更加抽象的變數名來代表這些地址。無論從理解還是記憶上都要方便的。

命名一定要“名副其實”,儘可能使用有意的名稱,而且這個意義和指稱的變數真實意義相關。

儘量不要出現沒有任何意義的命名類似於下述形式的命名:

int a = 1;

int b = 3;

CGPoint point = CGPointMake(a,b);

如果換成下面的形式是不是可讀性強了很多:

int startX = 1;

int startY = 3;

CGPoint startPoint = CGPointMake(startX,startY);

命名首字母大寫,其他命名首字母小寫。並且採用駝峰格式分割單詞。

例如:BWTest

使用能夠讀出來的名稱

人類長於記憶和使用單詞。大腦中的相當一部分就是用來容納和處理單詞的。單詞如果能夠讀的出來,則非常方便我們閱讀和理解。

錯誤的示例: genymdhms (生成日期,年、月、日、時、分、秒)

正確的例項: generationTimeStamp

使用可搜尋的名稱

單字母名稱和數字常量有一個問題,就是很難在一大篇文字中找出來。試想一下,你找~~~MAX_CLASSES_PER_STUDENT~~~容易還是找數字7容易。

檔名

檔名反映出了其實現了什麼類(包括大小寫),你需要遵循所參與醒目的約定。

檔案的副檔名及其意義如下:

類別的副檔名以“被擴充套件的類名+自定義命名部分組成”

例如:NSSstring+Utils.h

縮略詞

雖然方法命名不應使用縮略詞,然而有些縮略詞在過去被反覆的使用,所以使用這些縮略詞能更好的的表達程式碼的含義。下表列出了Cocoa可接受的縮略詞。

以下是一些常用的首字母縮略詞:ASCII,PDF,XML,HTML,URL,RTF,HTTP,TIFF,JPG,PNG,GIF,LZW,ROM,RGB,CMYK,MIDI,FTP…

巨集定義全部字母大寫,例如:#define BW_DEBUG 1

常量定義,字串定義以小寫字母 k 開頭,隨後首字母大寫

static NSString* const kBWBarTitle = @"動態";

如果要定義常量使用static const優於巨集定義,前者會進行型別檢查

因為OC沒有名稱空間的概念,所以使用前兩個或者多個字母來表示名稱空間,例如”NSObject中的NS”,我們也使用自己的名稱空間。比如

紅點中使用了VAS:VASAddValueInfo...

錢包中使用了QW:QWApplication....

註釋

讓程式碼自注釋,不要依賴註釋來解釋自己的設計或者編碼意圖。除了特殊情況外,程式碼中不要有多餘的註釋。

類與物件

明確指定建構函式

註釋並且明確指定你的類的建構函式。

對於需要繼承你的類的人來說,明確指定建構函式十分重要。這樣他們就可以只重寫一個建構函式(可能是幾個)來保證他們的子類的建構函式會被呼叫。這也有助於將來別人除錯你的類時,理解初始化程式碼的工作流程。 ###過載指

定建構函式

當你寫子類的時候,如果需要 init… 方法,記得過載父類的指定建構函式。

如果你沒有過載父類的指定建構函式,你的建構函式有時可能不會被呼叫,這會導致非常隱祕而且難以解決的 bug。

過載 NSObject的方法

如果過載了 NSObject 類的方法,強烈建議把它們放在 @implementation 內的起始處,這也是常見的操作方法。

通常適用(但不侷限)於init…,copyWithZone:,以及dealloc方法。所有init…方法應該放在一起,copyWithZone: 緊隨其後,最後才是dealloc 方法

觀察者模式

如果只是單純的傳遞資料,不要使用觀察者模式,容易導致邏輯鏈斷裂。

參考資料

1.《Clean Code》

2.《編寫可閱讀程式碼的藝術》

3.《Google Objective-C Style Guide》

4.《Introduction to Coding Guidelines for Cocoa》

5.《iOS應用開發最佳實踐系列一:編寫高質量的Objective-C程式碼》

相關推薦

Objective-C細節之中

Objective-C 是 C 語言的擴充套件,增加了動態型別和麵對物件的特性。它被設計成具有易讀易用的,支援複雜的面向物件設計的程式語言。它是 Mac OS X 以及 iPhone 的主要開發語言。 Cocoa 是 Mac OS X 上主要的應用程式框架之一。它由一

深入理解Objective-CCategory

fix 忽略 DDU 相關 情況 內存布局 先生 們的 ntc https://tech.meituan.com/DiveIntoCategory.html 摘要 無論一個類設計的多麽完美,在未來的需求演進中,都有可能會碰到一些無法預測的情況。那怎麽擴展已有的類呢?一般而言

Objective-cBlock

# Block 概述 標準C裡面沒有Block, C語言的後期擴充套件版本, 加入了匿名函式; C++、JS、 Swift等語言中, 有類似語法, 叫做閉包! block語法和函式指標很相似。回顧, C語言中的指標函式: c int(*) (int x,

Objective-C利用typedef為Block進行重新命名

typedef int (^Sum) (int,  int); 這樣我們就利用typedef定義了一個block,這個block的名字就是Sum,需要傳入兩個引數。當我們需要使用時,就可以這樣做了: Sum mysum = ^(int a, int b) { n =

Objective-c封裝、繼承與多型

面向物件的三個基本特徵是:封裝、繼承、多型。 封裝 簡介 封裝是實現面向物件程式設計的第一步,封裝就是將資料或函式等集合在一個個的單元中(我們稱之為類)。被封裝的物件通常被成為抽象資料型

[美團技術團隊]&深入理解Objective-CCategory

屬性列表 prop chm hooks 一段 eth found 為我 更多 [轉載]深入理解Objective-C:Category 來自:美團技術團隊 無論一個類設計的多麽完美,在未來的需求演進中,都有可能會碰到一些無法預測的情況。那怎麽擴展已有的類呢?一般而言,繼

第 1 條了解 Objective-C 語言的起源

還在 特性 只知道 程序 開發 不能 核心 nbsp 原因   馬上就要發布 Swift 4 了,自己也在學習 Swift,後面 iOS 編程估計也快是 Swift 的天下了,我卻還在這抱著一本講 OC 的書在啃,怪只能怪自己之前太懶了,按定價好幾十塊錢買的書不讀完,簡直對

Objective-C多態動態類型識別+動態綁定+動態加載

出錯 靜態類 檢查 而不是 memberof ati 運行 strong 函數指針 http://blog.csdn.net/tskyfree/article/details/7984887 一、Objective-C多態 1.概念:相同接口,不同的實現 來自不同類可以定義

排雷記錄Swift +Objective-C混合Framework的一些問題

對於Swift的出現,估計很多公司很多人都面臨著原有開發框架的更新換代,Swift經過一年的發展,到現在2.1版,顯而易見的大坑填的差不多了,算是基本堪以大用了,這場景讓我恍惚回到使用.Net 2.0架構軟體系統的年代,都是剛算夠上堪以大用,可以引入企業級開發了,可以考慮構

Objective-C Runtime 執行時之五協議與分類

Objective-C中的分類允許我們通過給一個類新增方法來擴充它(但是通過category不能新增新的例項變數),並且我們不需要訪問類中的程式碼就可以做到。 Objective-C中的協議是普遍存在的介面定義方式,即在一個類中通過@protocol定義介面,在另外

Objective-C Runtime 執行時之六拾遺

前面幾篇基本介紹了runtime中的大部分功能,包括對類與物件、成員變數與屬性、方法與訊息、分類與協議的處理。runtime大部分的功能都是圍繞這幾點來實現的。 本章的內容並不算重點,主要針對前文中對Objective-C Runtime Reference內容遺漏

Objective-C的屬性(property)解析

Property “屬性”(property)是Objective-C的一項特性,用於封裝物件中的資料。使用了屬性的話,編譯器就會自動編寫訪問這些屬性所需的方法(setter和getter),這個過程稱為“自動合成”(autosynthesis)。 @p

Objective-C Runtime 執行時之一類與物件

Objective-C語言是一門動態語言,它將很多靜態語言在編譯和連結時期做的事放到了執行時來處理。這種動態語言的優勢在於:我們寫程式碼時更具靈活性,如我們可以把訊息轉發給我們想要的物件,或者隨意交換一個方法的實現等。 這種特性意味著Objective-C不僅需要一

Objective-C Runtime 執行時之二成員變數與屬性

在前面一篇文章中,我們介紹了Runtime中與類和物件相關的內容,從這章開始,我們將討論類實現細節相關的內容,主要包括類中成員變數,屬性,方法,協議與分類的實現。 本章的主要內容將聚集在Runtime對成員變數與屬性的處理。在討論之前,我們先介紹一個重要的概念:型別

Objective-C Runtime 執行時之三方法與訊息

前面我們討論了Runtime中對類和物件的處理,及對成員變數與屬性的處理。這一章,我們就要開始討論Runtime中最有意思的一部分:訊息處理機制。我們將詳細討論訊息的傳送及訊息的轉發。不過在討論訊息之前,我們先來了解一下與方法相關的一些內容。 基礎資料型別 SEL

Objective-C Runtime 執行時之四Method Swizzling

理解Method Swizzling是學習runtime機制的一個很好的機會。在此不多做整理,僅翻譯由Mattt Thompson發表於nshipster的Method Swizzling一文。 Method Swizzling是改變一個selector的實際實現的

Objective C 學習心得 (一)--Windows下搭建objective C開發環境

      最近打算針對iPhone、iPod touch和iPad開發一些應用,所以,需要開始學習Objective C(蘋果推出的類似C語言的開發語言)。由於蘋果的自我封閉的產業鏈發展模式(從晶片、機器、開發語言、終端產品、服務)的限制,要想開發針對蘋果iPhone等產品

IOS基礎深入理解Objective-c中@class的含義

objective-c中,當一個類使用到另一個類時,並且在類的標頭檔案中需要建立被引用的指標時, 如下面程式碼:  A.h檔案 #import "B.h"   @interface A : NSObject {        B *b;    }    @end

Swift開發指南使用Swift與Cocoa和Objective-C(Swift 4)

與Objective-C API進行互動 互操作性是能夠在任何一個方向上與Swift和Objective-C進行介面,讓您訪問並使用以其他語言的檔案中的一些程式碼。當您開始將Swift整合到應用程式開發工作流程中時,瞭解如何利用互操作性來重新定義、改進和增

Objective-C Runtime 總結訊息機制 篇

Objective-C語言是一門動態語言,它將很多靜態語言在編譯和連結時期做的事放到了執行時來處理。這種動態語言的優勢在於:我們寫程式碼時更具靈活性,如我們可以把訊息轉發給我們想要的物件,或者隨意交換一個方法的實現等。 與Runtime互動 Objc 從