OC語法總結

1、定義類:
@interface 類名 : 父類
@end

2、使用:(冒號)表示繼承一個類
Student : NSObject

3、使用()定義一個Catagory(類別)

* 作用:在不改變原有類結構的基礎上,擴展原有類的方法(不能擴展屬性),但不建議重載原有類的方法

* 開發工具默認生成的文件爲:類名+Catagory名稱
* Catagory可以寫在單獨的文件中,也可以寫在原有類的文件中,如何寫根據需求來決定。

4、使用<>表示實現一個Protocol(協議),如需實現多個協議,將協議名以逗號分隔都寫在括號中即可
*可以理解爲java中的接口,但不同的是,實現類編譯器不強制實現Protocol中定義的所有接口
* 在方法簽名上標識:@required,從字面上理解實現類必須實現該方法,其實寫與不寫一樣的效果。也是默認的
* 在方法簽名上標識:@optional,表示實現類對該方法的實現,是可選的。
  
5、屬性的訪問權限
* private : 只有類內部可以訪問
* protected : 類內部和子類可以訪問(默認)
* public : 訪問沒有限制

例:

// 定義

@interface Student : NSObject {
@private int _age;
@protected int _no;
@public float _height;
}
@end

// 使用
Student *stu = [[[Student alloc]init]autorelease];
stu->_height = 20;// 直接讀寫屬性的值,開發當中一般不建議這麼做。違背了面向對象的開發原則-》封裝性

6、屬性的定義與封裝
// in Student.h
@interface Student : NSObject {
// 1. 定義屬性,默認訪問權限是@protected的,只有自已和子類可以直接訪問
int _age;// OC語法中建議屬性名前面加上下劃線,以和參數名區分
int _no;
}

// 2.提供屬性對外讀寫方法的聲明,供外界調用。OC創建屬性讀寫方法的命名規則是爲,set方法: set+屬性名,get方法:屬性名
// 聲明age的get和set方法
- (int)age;
- (void)setAge:(int)age;

// 聲明no的get和set方法
- (int)no;
- (void)setNo:(int)no;
@end

// in Student.m 實現頭文件中的方法
#import "Student.h"// 導入頭文件
@implementation Student

// 實現頭文件中的方法
- (int)age { // age的getter方法
return _age;
}

- (void)setAge:(int)age {// age的setter方法
_age = age;
}

- (int)no {
return _no;
}

- (void)setNo:(int)no {
_no = no;
}
@end

7、使用@synthesize自動生成屬性getter和setter方法的實現,同時會生成一個下劃線(_)+屬性名的成員變量。需要和@property配合使用。例:
@implementation Student

@synthesize age;// 這一句頂下面的get和set方法,由@synthesize自動生成
/*
* 1. 如果顯示實現了get方法,@synthesize會自動生成屬性的set方法實現
* 2. 如果顯示實現了set方法,@synthesize會自動生成屬性的get方法實現
* 3. 如果即沒有實現get方法,也沒有實現set方法,則@synthesize會自動生成屬性的get和set方法實現
*/
- (int)age { // age的getter方法
return _age;
}

- (void)setAge:(int)age {// age的setter方法
_age = age;
}

@end

注:在xcode4.5以後的編譯環境中,不需要寫@synthesize聲明生成屬性的get和set方法實現。只需要在頭文件中用@property定義即可自動在.m文件中生成相應屬性的get和set方法實現


8、使用@property聲明一個屬性,編譯器會自動生成該屬性的getter和setter方法的聲明

在xcode4.5以後版本的編譯器環境中,會自動在.m文件中生成該屬性getter和setter方法的標準實現,不需顯示聲明用@synthesize來生成屬性的getter和setter方法實現。


9、@property屬性參數
1> nonatomic : 多線程環境下,不需要線程保護(讀寫時不加鎖), 
  atomic : (默認)多線程環境下需要線程保護(讀寫時加鎖).
2> readonly : 表示在.m文件中只生成屬性的getter方法的實現
  readwriter : 表示在.m文件中生成屬性的getter和setter方法的實現(默認)
3> retain : 表示調用該屬性的setter方法時,先release舊的值,再retain新的值。一般聲明的成員變量是NSObject的子類纔會添加該參數
  assign : 生成標準的getter和setter方法實現(默認),直接給屬性賦值
4> getter= : 表示自定義屬性生成的getter方法名稱
  setter= : 表示自定義屬性生成的setter方法名稱

10、方法調用
* [實例對象 方法名:參數列表]
* [類名 方法名:參數列表]
例:
Student *stu = [[[Student alloc]init]autorelease];
[stu setAge:22 andNo:10];// 調用實例方法

[Student initWithAge:20];// 調用靜態方法

11、點(.)語法
Student *stu = [[[Student alloc]init]autorelease];
stu.age = 20; // 相當於調用了對象的setAge方法(寫)
int age = stu.age;// 相當於調用了對象的getAge方法(讀)

12、self關鍵字
相當於java中的this,不同的是self在不同的環境下,作用也不同。在實例方法中self可以當該對象使用,在靜態方法中,self可以當類對象使用。
如:
- (void)age {
   return self.age;// 這裏self是實例對象本身
}

+ (id)newInstace {
//Student *stu = [[[Student alloc]init]autorelease];
Student *stu = [[[self alloc]init]autorelease];// 這一句和上一句代碼的效果是等效的,而在java語法是不允許this出現在靜態方法中的
return stu;
}
  

13、@class : 在頭文件中聲明一個類的存在

爲了提高效率,在只需要知道類的存在的情況下,不需要導入某個類的頭文件。

// #import "Book.h"
@class Book; // 不需要導入Book.h頭文件,在.m文件真正使用的時候再導入
@interface Student : NSObject
@property Book *book;
@end

14、@protocol : 在頭文件中聲明一個協議的存在

目的和@class一樣


15、^ : 定義一個Block類型,與標準C語法中指向函數指針類型的寫法非常相似
如:定義一個sum的Block類型,返回值爲int,有兩個int形參
int (^sum) (int, int) = ^(int a, int b) {
return a + b;
}; 

16、#import : 用於導入一個類的頭文件
#pragma mark : 寫方法的註釋
#pragma mark - : 方法註釋分組
+ : 聲明或定義一個靜態方法
- : 聲明或定義一個實例方法

17、方法定義(一個冒號代表一個參數,冒號也是屬性方法的一部份)
方法類型 (返回值類型)方法名稱[參數列表] {(一個冒號代表一個參數,冒號也是屬性方法的一部份)
// 方法體
}

* 實例方法,方法名: sumAge:andNo:
- (int)setAge:(int)age andNo:(int)no {
// 在這裏插入代碼邏輯
}

* 靜態方法
+ (id)initWithAge:(int)age {
// 在這裏插入代碼邏輯
}
注:
* 實例方法通過類的實例對象訪問
* 靜態方法通過類名或self訪問

18、內存管理
 1> 凡是從NSObject中繼承的類都需要自己管理內存,在OC語法中,創建的任何一個對象都擁有一個引用計數器,第一次創建的時候這個引用計數器爲1,當引用計數器的值爲0時,該對象會被銷燬。內存管理涉及到以下接口:
  * release : 對象的引用計數器減1
  * retain : 對象的引用計數器加1
  * retainCount : 獲取對象當前引用計數器的數量
 
  對象生命週期回調接口:
  * init : 對象的默認構造方法,如果自定義構造方法用於初始化成員變量時,必須先調用父類的構造方法,並判斷獲得的對象是否爲nil,再初始化成員變量。
  如:- (void)initWithAge:(int)age {
     if ( self = [super init] ) {
         _age = age;
 }
 return self;
 }
 
  * dealloc : 對象銷燬時,系統會自動調用該方法,通常在該方法中釋放內存或其它資源。在重寫dealloc方法時,注意在代碼最後面調用父類的dealloc方法,用於釋放內存等相關資源。

 如:

- (void)dealloc {

 [_book release];// 釋放成員變量
 [super dealloc];
 }
 
 2> 不需要管理內存的對象
  * 基本數據類型
  * 系統自帶的類調用自己的靜態方法創建的對象,是自動釋放內存的,不需要管理
 
 3> 內存管理原則
  只有向對象發送了alloc,retain,copy,new消息纔有必要做release操作
  * 誰alloc,retain,copy,new誰release
  * 誰創建誰釋放(release)
  * 誰沒有allock,retain,copy,new,你就不要做release操作
 
 4> 自動內存管理(由autoreleasepool管理)
  在創建對象的同時,調用autorelease方法,會將該對象的一個引用自動存放到最近創建的一個自動釋放釋放池中。以後該對象就不需要手動來release操作,徐非做了retain,copy等修改了引用計數器的操作。當自動釋放池被銷燬時,會向池子中所有對象發送一個release消息,池子中的所有對象的引用計數器此時會減1,只有當池子中的引用計數器爲0時,該對象纔會被徹底銷燬。不是說只要將對象交給自動釋放池了,池子被銷燬,池子中的所有對象就一定會被銷燬。
 

 如:@autoreleasepool {

 Student *stu = [[[Student alloc] init]autorelease];// 此時stu對象將放到這個大括號中的自動釋放池子中
 
  [stu retain];// 如果加了這一句,此時stu的引用計數器爲2,這時候如果在池子銷燬前沒有向對象發送release消息,就算池子銷燬,該對象也還是會造成內存泄露
 
  } // 程序執行到此處,代表自動釋放池被銷燬,意味着池子中的所有對象都會接到一個release消息

19、OC中的類似Java的toString方法
Student *stu = [[[Student alloc]init]autorelease];
NSLog(@"%@",stu);// 默認打印的是stu對象的內存地址

* 重寫父類的description方法,可自定義打印對象的信息
- (NSString *)description {
   NSLog(@"age is %i",_age);

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章