天天看點

016-類與對象-OC筆記

1.【了解】對象在記憶體中的存儲

2.【了解】nil和null

3.【了解】#pragma mark分組導航标記

4.【了解】方法與函數

5.【掌握】多檔案開發

6.【掌握】對象和方法

7.【掌握】對象和屬性

類加載:

當程式啟動時,會附加元件目中所有的類和分類,而且加載後會調用每個類和分類的+load方法,而且隻會調用一次。并且類一旦加載到記憶體,就不會被回收,直到程式結束的時候才會被回收。這個過程就叫做類加載。

當第一次使用某個類建立對象的時候,就會調用目前類的+initialize方法,也就是初始化對象,使建立出來的對象可以使用。

對象在記憶體之中是如何存儲的呢?我們這裡的p指針是在函數中聲明的,那麼p就是一個局部指針變量,也就是p變量存儲在棧空間中。比如:

int main(){

    person *p = [person new];

    return 0;

}

new做了什麼事情?

1.申請空間:在堆記憶體之中根據類的“模闆”申請一塊合适大小的空間建立對象。類“模闆”中有哪些屬性,就把這些屬性聲明在這塊空間之中。對象中聲明了類定義的所有的屬性和_isa指針和引用計數器(_isa指針指向代碼段中的類)。

2.初始化對象:初始化這塊空間之中對象的屬性的值,就是為屬性賦預設值。

3.傳回對象位址:傳回這塊空間的記憶體位址。

通過指針通路對象的屬性和方法?

1.通路屬性:通過指針可以找到指針指向的堆空間中的對象,找到對象後就可以直接通路對象的屬性。

2.調用方法:根據指針找到堆空間中的對象,在根據對象中的_isa指針找到代碼段中的類中的方法。

null是c中指針變量的值,代表這個指針不指向任何變量,這個時候null等價于0。

int *p = null;//等價于int *p = 0;

nil是oc中指針變量的值,代表這個指針不指向任何對象,這個時候nil等價于0。

person *p = nil;//等價于person *p = 0;

注意:

1.其實null和nil都是一個宏,并且宏值都是0。隻不過null是在c語言中聲明的宏,nil是在oc中聲明的宏。是以在使用的時候應該區分開來使用。在oc中盡量使用nil,c中隻能使用null。

2.如果一個類指針沒有指向任何對象,通過這個指針去通路對象的屬性的時候會報錯。通過這個指針去調用方法的時候不會報錯,但是不會有任何回應。

1.#pragma mark 分組名

在導航欄顯示分組名

2.#pragma mark -

在導航欄顯示一條水準線

3.#pragma mark - 分組名

在導航欄顯示分組名,分組名上面加一條水準線

函數指的是c語言中的函數,方法指的是定義在oc類中的方法。

不同點:

1.函數除了不能定義在@interface之中,可以定義在源檔案中其他的任意地方(建議不要寫在類中)。方法的聲明隻能寫在@interface中,方法的實作隻能寫在@implementation中(文法強制要求)。

2.函數可以直接調用(函數是孤立的)。而方法隻能建立對象,通過對象名來調用(方法歸屬于類或者對象)。

相同點:

1.無論是函數還是方法,他們都是封裝了一個代碼塊,代表一個單獨的功能。

如果我們開發一個程式,不可能将所有的類都寫在同一個源檔案,後期維護和團隊開發都非常不友善。是以我們需要分子產品開發,并且每個子產品包含兩個檔案,分别是類的聲明檔案和實作檔案。類的聲明寫在.h檔案,類的實作寫在.m檔案(類的實作裡也要引入類的聲明檔案),使用這個類之前用#import引入.h檔案就行了。

建立檔案的時候選擇cocoa class,檔案名使用類名,就會同時建立類的聲明檔案和類的實作檔案。然後我們在.h檔案中寫類的聲明,在.m檔案中寫類的實作。例如:

person.h檔案

#import

@interface person : nsobject

{

@public

    nsstring *_name;

- (void)sayhi;

@end

person.m檔案

#import "person.h"

@implementation person

- (void)sayhi{

    nslog(@"你好%@",_name);

main.m檔案

int main(int argc, const char * argv[]) {

    @autoreleasepool {

        person *p = [person new];

        p -> _name = @"jack";

        [p sayhi];

    }

對象可以作為方法的參數,因為類的本質就是一個資料類型。并且傳遞的時候是位址傳遞,相當于在方法中操作的參數和實參是同一個對象。

gender.h檔案

//單獨在一個頭檔案中定義一個性别枚舉

typedef enum{gendermale,genderfemale}gender;

#import "gender.h"

    gender _gender;

    int _age;

//人的打招呼方法聲明

//人的打招呼方法實作

    nslog(@"我是%@,性别%@,年齡%i",_name,_gender == 0 ? @"男" : @"女",_age);

god.h檔案

@interface god : nsobject

//上帝的打招呼方法聲明

//上帝殺死一個人的方法聲明

- (void)killwithperson:(person *)person;

god.m檔案

#import "god.h"

@implementation god

//上帝的打招呼方法實作

    nslog(@"我是%@,性别%@",_name,_gender == 0 ? @"男" : @"女");

//上帝殺死一個人的方法實作

- (void)killwithperson:(person *)person{

    person -> _age = 0;

    nslog(@"%@已經被%@殺死",person -> _name,self -> _name);

        //執行個體化一個人對象

        //給這個對象的成員變量指派

        p -> _name = @"小明";

        p -> _gender = gendermale;

        p -> _age = 21;

        //調用這個對象的打招呼方法

        [p sayhi];//輸出 我是小明,性别男,年齡21

        //執行個體化一個上帝對象

        god *g = [god new];

        g -> _name = @"上帝";

        //調用這個對象的殺死人方法

        [g killwithperson:p];//輸出 小明已經被上帝殺死

        nslog(@"小明的壽命等于:%i",p->_age);//輸出 小明的壽命等于:0

//上帝造人的方法

- (person *)makepersonwithname:(nsstring *)name;

- (person *)makepersonwithname:(nsstring *)name{

    p -> _name = name;

    nslog(@"上帝制造了一個叫%@的人",p -> _name);

    return p;

        //上帝制造了一個人

        person *p = [g makepersonwithname:@"小明"];//輸出 上帝制造了一個叫小明的人

        //給制造出來的對象的成員變量指派

        p -> _age = 19;

        //調用這個對象的方法

        [p sayhi];//輸出 我是小明,性别男,年齡19

對象可以作為類的執行個體變量,比如我們有一個人類和一個狗類,每一個人擁有一隻狗,那狗也是人的屬性了。比如:

dog.h檔案

@interface dog : nsobject

@property (nonatomic,copy) nsstring *name;//狗名

- (void)shout;//狗叫的方法聲明

dog.m檔案

#import "dog.h"

@implementation dog

//狗叫的方法實作

- (void)shout{

    nslog(@"叫%@的狗叫了",_name);

@property (nonatomic,retain) dog *dog;//人的狗

        person *person = [[person alloc] init];

        //給人對象的dog成員指派一個狗對象

        person.dog = [[dog alloc] init];

        person.dog.name = @"小白";

        //調用狗對象叫的方法

        [person.dog shout];

轉自:http://blog.csdn.net/qq_31810357