1、const(常量---readonly)
作用:
- 用于修飾 右邊 的基本變量或指針變量;
- 被修飾的變量只讀,不能被修改(readonly);
定義的意義:
(1.) 常用使用方式:
- 常用單獨使用形式有三種:(但是一般會和其他關鍵字聯(lián)合使用)
const NSString * name = @"jack";
NSString const * sax = @"boy";
NSString * const age = @"24";
這樣定義的均為全局常量:不管你定義在那個文件夾(單獨定義現(xiàn)在只能存在于.m文件中,見:用法舉例->PS),在外部的任意文件中都可以訪問到。
- 和其他關鍵字結合使用的形式一般有兩種:
extern const NSString * name; // 僅做聲明使用,一般存在與.h文件中
static const NSString * name = @"jack"; // 使全局常量變?yōu)榫植孔兞浚唧w使用后面會介紹??
(2.)const究竟做了什么?
在介紹const時著重強調了“右邊”二字,這是有原因的O(∩_∩)O~
在使用時我們發(fā)現(xiàn)const 修飾時 位置是不一樣的,不同位置分別代表了什么含義呢?
const NSString * name = @"jack";
// *name 不能修改 name 可以修改 ---> *name 是指向指針的指針~
NSString const * sax = @"boy";
// 與上面一樣(這就是為什么強調“右邊”二字了)
NSString * const age = @"24";
// *name 能修改 name 不可以修改 --->所以我們想定義一個不想被修改的常量應該這樣
我們可以用指針變量來驗證一下:
用法舉例:
訪問的方式一般有兩種:
(1.)在.m文件中定義,在其他文件中獲取其聲明,然后使用;
(2.)另一種使用時需要先在.h中聲明,然后.m中賦值,當要使用該常量時需要導入定義該常量的頭文件,然后直接使用即可。
PS:現(xiàn)在不能直接在.h文件中定義常量了,會發(fā)生循環(huán)引用問題。具體見http://www.lxweimin.com/p/94ca52399ade該篇文章的第十五小標題,所以現(xiàn)在常用方法是單獨創(chuàng)建一個專門存放常量的文件,使用第二種方法定義常量,然后在pch文件中導入該文件的頭文件。
2、static (靜態(tài)的)
作用:修飾不同的變量作用不盡相同。
(1.)修飾全局變量:
static NSString * name_boy = @"Bob";
// 下面是與const結合使用的情況
static const NSString * name = @"jack";
static NSString const * sax = @"boy";
static NSString * const age = @"24";
這又分為兩種:
---》在.h中修飾全局變量:
現(xiàn)在直接在.h文件中定義全局變量或者const修飾的全局變量運行時會直接報_x86的錯誤,但是可以使用static 修飾,即可在.h文件中定義,然后在其他文件中可以直接使用!
---》在.m中修飾全局變量:
改變全局變量的作用域,使全局變量的作用域僅限于當前文件內部(.m內部),即當前文件內部才能訪問該全局變量。同時這樣能夠避免重復定義全局變量!常見的使用情況:單例中。
若將上圖(2-1-定義)中static const NSString * name = @"jack";
放到.m文件中則在AppDelegate.m中則訪問不到name
.
(2.)修飾局部變量:
---》改變局部變量的生命周期(只到程序結束,這個局部變量才會銷毀)不會改變局部變量的作用域;
---》讓局部變量只初始化一次,局部變量在程序中只有一份內存
下面有一組對比來說明修飾局部變量后的變化:
可以看到,經(jīng)過static修飾后,在for循環(huán)內部workDays只被初始化了一次。
與const結合使用:
一般是在.m文件中定義經(jīng)常使用的字符串常量,或者數(shù)值常量時使用。static將一個全局變量變成局部變量,然后const將一個局部變量變成局部常量
e.g : MBProgressHUD.m中
3、extern(外部的,外部變量)
作用:
- 用來聲明全局變量;
- 只是用來獲取全局變量(包括全局靜態(tài)變量)的值,不能用于定義變量;
用法:
- 在.h中修飾聲明全局變量,然后在.m中定義該全局變量,則在其他文件中可以直接使用該變量!
- 獲取全局變量的值(具體用法參考本篇文章中const篇幅中 -> 用法舉例 中的(1.);
與const結合使用:
即,在.h中聲明一個const修飾的全局變量,讓后再在.m中實現(xiàn)其定義。(這樣逼格看起來要高一些,其實就是定義了一個全局變量~)
在這里還有一些關鍵字UIKIT_EXTERN、OBJC_EXTERN、FOUNDATION_EXTERN、FOUNDATION_EXPORT、FOUNDATION_IMPORT,這些均為經(jīng)過處理的extern.
- UIKIT_EXTERN:將函數(shù)/變量修飾為兼容以C編譯方式的、具有extern屬性的屬性。
- OBJC_EXTERN:與UIKIT_EXTERN差不多,但是比其更加寬泛一些。
- FOUNDATION_EXTERN:看其定義是與OBJC_EXTERN一毛一樣的······
- FOUNDATION_EXPORT/FOUNDATION_IMPORT:用來兼容win32應用程序,同時也是為了兼容C++語言的~~(不明覺厲??)
若是使用以上字段是不是看起來逼格又高了一點~~,不過通常使用最多的也就是 UIKIT_EXTERN了。
4、typedef(定義類型)
作用:定義類型的別名。
(1.)定義枚舉:
typedef NS_ENUM(NSInteger, UITableViewStyle) {
UITableViewStylePlain,
UITableViewStyleGrouped
};
typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
UISwipeGestureRecognizerDirectionRight = 1 << 0,
UISwipeGestureRecognizerDirectionLeft = 1 << 1,
UISwipeGestureRecognizerDirectionUp = 1 << 2,
UISwipeGestureRecognizerDirectionDown = 1 << 3
};
//凡是需要以按位或操作來組合的枚舉都應使用NS_OPTIONS定義。若是枚舉不需要互相組合,則應使用NS_ENUM來定義
(2.)定義block:
typedef void (^JRNetWorkSuccessBlock)(id responseObject, MBProgressHUD * hud);
(3.)添加別名:
typedef NSString Str;
// 這樣再定義string類型時,也可以直接使 Str
// e.g @property (copy, nonatomic) Str * name;
5、typeof(變量名,類型)
作用:靜態(tài)獲取參數(shù)類型。
最常見就是自定義block中防止循環(huán)引用:
__weak typeof(self)weakSelf = self;
self.channelHeaderView.addAction = ^{
[[UIApplication sharedApplication].keyWindow addSubview:weakSelf.channelView];
};
6、define(定義)
作用:主要是用于定義宏
關于宏定義可以看一下我的這篇文章 《iOS預編譯指令詳解》。對于經(jīng)常使用的一些常量最好使用const而不是定義成宏。