OC之對象在內存的位置


對象在內存中的存儲

1. 內存中的五大區域.

    棧: 存儲局部變量.

    堆: 允許程序員手動在堆區申請指定的連續的字節數的空間來使用.

    BSS段: 存儲未初始化的全局變量、靜態變量.

    數據段(常量區):  存儲已經初始化的全局變量、靜態變量、常量數據.

    代碼段:存儲程序的代碼.

2. 類加載.

    1). 當創建對象的時候,肯定需要訪問這個類.因為只有訪問了類才知道類中有那些成員.

    2). 如果只是聲明類指針的時候,也會訪問這個類.以確定這個類型是否存在.

    當類第一次被訪問的時候,會將類存儲到代碼段之中. 這個過程叫做類加載.

    將類的代碼存儲在代碼之中.

    將類的代碼以字符串的形式存儲在代碼段中.

    只有類第1次被訪問的時候,才會有類加載.   

    一旦類被加載到代碼區.直到程序結束的時候才會被回收.

3.對象在內存中是如何存儲的.

   1). 類的本質是:自定義的數據類型.

       HMPerson *p1 = [HMPerson new];

   2). HMPerson *p1;

       這句話,僅僅是聲明了1個指針變量而已.這個指針變量的類型是HMPerson*.

       p1是1個局部的變量.所以p1指針變量是存儲在棧區的.

       p1是1個指針變量,所以這個變量中只能存儲地址.

       本質上來講.p1是1個指針變量 不是1個對象.

    3).[HMPerson new];

       這句話,才是在真正的創建對象.

       new做的事情.

       a. 在堆內存中申請一塊合適大小的空間.

       b. 在申請的這塊空間中根據類的模板創建對象.

          類中有哪些屬性.就把類的屬性依次的挨個的一個不落的聲明在這個對象中.

          對象中除了有類中定義的屬性之外,還有1個屬性叫做isa 這是1個指針.

          這個isa指針指向代碼段中的類.

       c. 初始化對象的屬性.為對象的屬性賦默認值

          -> 如果屬性的類型是基本數據類型.就賦值為0

          -> 如果屬性的類型是C指針類型.就賦值為NULL

          -> 如果屬性的類型是OC指針類型.就賦值為nil

       d. 返回這個對象在堆空間中的地址.

          將這個地址賦值給p1指針.

          p1指針指向了堆空間中的HMPerson對象.

    4). 注意

        a. 對象中只有類的屬性+isa的指針. 沒有方法.

           isa指針指向了代碼段中的類.

        b. 如何訪問對象的屬性.

           通過指針就可以找到指針指向的對象.找到對象了,就可以找到對象的屬性.

          p1->_name = @"jack";

        c. 如何調用對象的方法?

           [p1 sayHi];

           通過p1指針找到對象,發現是在調用方法.那么再根據對象的isa指針找到代碼段中的類.

           再找到類中的對應的方法來執行.

        d. 為什么方法不保存在對象中.

           因為不管對象有多少個.方法的代碼都是一樣的.沒有必要保存多份,只保存1份就可以了.

        e. 相同類的對象的isa指針的值一定都是一樣的.

4. 對象的屬性的初始值.

    創建1個對象 如果沒有為這個對象的屬性賦值.那么這個對象的屬性是有值的.

    屬性的類型是基本數據類型:  0

              OC指針:      nil

              C指針:       NULL

         

Nil

1. C語言中學習的NULL.

    a). NULL是1個值. 是C語言中指針變量的值.

    b). 如果1個指針的值為NULL值,就代表這個指針不指向內存中的任何空間.

    c). NULL本質上是1個宏.

        define NULL ((void*)0)

        所以 NULL 和 0 等價.

2. nil

    a). nil也是1個值. 它也是1個指針變量的值.

    b). nil的本質也是1個宏.

        #define __DARWIN_NULL ((void *)0)

        所以,nil和NULL完全是等價的.

c). 所以,如果

想要讓1個指針不指向任何空間.

        可以為這個指針變量賦值為NULL nil 0

3. 使用建議

    a). 如果希望C指針不指向任何空間.一般為其賦值為NULL

    b). 如果希望OC指針不指向任何空間,一般賦值nil

4. 注意問題

    如果1個類指針的值為nil

    HMPerson *p1 = nil;

    代表p1指針不指向任何對象.

     1). 所以這個時候 通過p1去訪問p1指向的對象的屬性的時候,肯定的會報錯.

        對象都沒有 哪里來的屬性呢?

    2). 這個時候, 通過這個指針去調用方法的時候,

        不會報錯.也不會崩潰.

        只是沒有任何反應的啦.

分組導航標記

1. 一種快速的方式查找文件中的代碼.

    Xcode 提供了導航條可以快速查找.

2. 分組導航標記.

    1). #pragma mark 標記名.

    2). #pragma mark -  就會產生1條分割線.

3). #pragma mark - 標記名.  就會產生1條分割線.並取1個標記名.

方法與函數

1. 之前在C語言中叫做函數.

    void test();

    在OC類中定義的叫做方法.

    - (void)sayHi;

2. 相同點:

    1). 都封裝1段代碼,都表示1個相對獨立的功能.

    2). 函數/方法 如果不被調用,那么其中的代碼是不會被執行.

3. 不同點.

    1). 語法不同.

    2). 定義的位置不一樣.

        a. 函數除了函數的內部和@interface的大括弧中不能定義.其他的地方都是可以定義的.

        b. 而方法的聲明只能在@interface的大括弧的外面,實現只能在@implementation中.

        就算把函數寫在類中,這個函數也不是屬於這個類的.

    3). 歸屬感不同.

        a, 函數就像是1個沒有家的孩子,每1個函數是孤立的.]

        b. 方法是屬於類的.類就是方法的家.

    4). 調用形式不同.

        a. 函數直接調用.

        b. 方法必須要通過對象名來調用.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM