Effective Objective-C 2.0 總結與筆記(第一章)—— 熟悉Objective-C
阿新 • • 發佈:2018-11-16
第一章:熟悉Objective-C
本章主要是對Objective-C進行一個瞭解,通過介紹Objective-C的語法,來講解Objective-C的基礎知識。
第1條:瞭解Objective-C語言的起源
- Objective-C語言採用“訊息結構”而非“函式呼叫”,雖然也是一門面向物件的語言,但是語法比較特別。
//訊息結構:(Objective-C) Object *obj = [Object new]; [obj doSomethingWith:someParams]; //函式呼叫:(C++) Object *obj = new Object(); obj->doSomething(someParams);
採用訊息結構的語言:執行程式碼由執行環境決定。
採用函式呼叫的語言:執行程式碼由編譯器決定。
- Objective-C的物件所佔記憶體分配在堆空間,不能在棧空間中分配Objective-C物件。通常Objective-C物件型別有一個
*
。
/* someString -> 分配在堆裡的某塊 含有一個叫"the string"的NSString物件 的記憶體 anotherString -> someString 指向的那塊記憶體 只有1個NSString例項,2個變數(指標)在棧幀中被分配了兩個記憶體,記憶體的值都是上面的堆記憶體地址 */ NSString *someString = @"the string"; NSString *anotherString = someString;
在Objective-C中不含*
的可能會使用棧記憶體,例如CGFloat
、CGRect
etc.
第2條:在類的標頭檔案中儘量少引入其他標頭檔案
- 引入有必要的標頭檔案,防止耦合。
- 當只需要知道這個類名,而不需要使用到裡面的一些方法,我們可以使用向前宣告的方式代替
#import
方案。
//向前宣告
@class someClass;
- 如果在各自的標頭檔案裡引入對方的標頭檔案,雖然不會像C++那樣導致死迴圈,但是會導致某個類無法被正確編譯。
第3條:多用字面量語法,少用與之等價的方法
- 什麼是字面量語法?
以一種簡潔的方式就可以建立物件的方法,而不需要使用alloc
init
來分配記憶體並進行初始化。並且除了字串以外,所建立的物件必須屬於Foundation框架。
example:
NSString *someString = @"the String";
- 字面量的各種例子:
//字面量字串
NSString *someString = @"the String";
//字面量數值
NSNumber *intNumber = @1;
NSNumber *floatNumber = @1.5;
//字面量陣列
NSArray *animals = @[@"cat", @"dog", @"mouse"];
NSString *dog = animals[1];
//字面量字典
NSDictionary *personData = @[@"firstName" : @"Matt",
@"lastName" : @"Gallway",
@"age" : @25];
NSString *firstName = personData[@"firstName"];
- 使用字典或者陣列的時候,如果值中有nil,則會丟擲異常。
第4條:多用型別常量,少用#define預處理指令
- 由於Objective-C裡沒有名稱空間的概念,所以如果使用預處理指令放在標頭檔案裡,那麼引入該標頭檔案的所有相關屬性都會被替換,當常量名稱可能衝突的時候,就可能存在一些隱藏的bug。
- 儘量不要在標頭檔案裡宣告常量,應該在實現的程式碼裡去宣告。同時為了防止佔用系統的名稱空間,通常每個工程對常量的命名都有自己的命名規範,一般在前面加k。
example:
// EOCAnimatedView.h
#import <UIKit/UIKit.h>
@interface EOCAnimatedView : UIView
- (void)animate;
@end
// EOCAnimatedView.m
#import "EOCAnimatedView.h"
static const NSTimeInterval kAnimationDuration = 0.3;
@implementation EOCAnimatedView
- (void)animate {
[UIView animateWithDuration:kAnimationDuration animations:^{
//dosomething()
}];
}
@end
一定要用const和static來同時修飾該常量,const表示不可被修改,而static則意味著該變數僅在定義此變數的編譯單元可見。
- 可以定義一個常量為其他檔案所用,此類常量通常放在“全域性符號表”中。
example:
//header file
extern NSString *const EOCStringConstant;
//implementation file
NSString *const EOCStringConstant = @"VALUE";
編譯器看到extern
關鍵字,就知道在全域性符號表裡有一個名為EOCStringConstant
的符號,編譯器無需檢視定義,允許程式碼使用,因為連結成二進位制檔案後可以找到這個常量。
第5條:用列舉表示狀態、選項、狀態碼
- 一般情況下,編譯器會為列舉分配一個獨有的編號,從0開始,每次遞增1。
- 建議使用如下方式來宣告列舉:
typedef NS_ENUM(NSUInteger, EOCConectionState) {
EOCConectionStateDisConnected, //default 0
EOCConectionStateConnecting, //default 1
EOCConectionStateConnected //default 2
} ;
是這樣在使用的時候就可以直接使用EOCConectionState
作為型別進行宣告列舉。其實EOCConectionState
本質就是NSUInteger
。
- 列舉的命名應當通俗易懂,意義區分明顯,不要出現混淆的情況。