天天看點

OC-類對象OC-類對象

OC-類對象

  • 在OC中,類本身就是對象, 他們是類名為Class的特殊類的執行個體
  • 即你不必做任何事情來執行個體化類對象,比一期将通過類定義中的資訊為你建立他們
  • OC中的類對象不具有執行個體變量,即無類變量
  • 但是,在OC中可以使普通的C語言的外部變量來模拟類變量
  • 我們可以這樣使用類對象
  • Class類型
  • 類型化為Class的變量用于指向類對象的指針, 可以這樣獲得這個指針
Class aClass = [NSString class]; //Class天生就是一個指針類型
    Class aClass = [NSString superclass];
           
  • Classl類型變量可以代替類名作為類方法的接收者(那為什麼,還要使用他呢?)
//比如,你要建立一個對象,但是新對象的類直到運作時才能知道。
    NSString* className = ...;//需要讀取配置檔案
    Class classToInstantiate = NSClassFormString(className);
    id newObject = [[classToInstantiate alloc] init];
           
  • 類方法
    • 類方法是在類的類對象上定義的方法,即類對象是類方法對應的消息接收者
    • 聲明方式類似執行個體方法,例如: +(id) alloc;
    • 類方法中當然不能直接通路執行個體變量
    • 類方法可以被子類繼承,子類可以重寫類方法
    • 應注意: 類方法中的self指的是類對象,而不是類的執行個體
    • 便利構造函數、
      • 即在單個方法中結合了配置設定和初始化,做用于類對象

        例如: NSString* emptyString = [NSString string];

      • 應注意的是: 你不擁有通過便利構造函數傳回的對象
      • 便利構造函數建立的一般規範:

        +(id) dog

        {

        //self, 保證子類也可以很好的使用這個方法

        return [[[self alloc] init] autorelease]; //即你你不擁有通過便利構造函數傳回的對象

        }

      • 如果計劃,擷取便利構造函數傳回的對象,你就要得到他的所有權

        Dog* dog = [Dog dog];

        [dog retain];

  • 類的初始化
    • 第一次使用類對象時(向類對象發送alloc消息時),會引起initialize消息的調用
    • 我們可以重寫這個方法,一般,我們是不需要去重寫的
    • initialize方法是有問題的
      • 若父類重寫的initialize方法,而子類沒用重寫
      • 則父類的initialize方法可能會被兩次調用,分别為:第一次使用父類, 第一次使用子類
      • 我們應通過判斷, 将初始化僅限于父類
+(void) initialize
    {
        if( self == [Dog class] )
        {
            //TODO
        }

    }
           
  • 模拟類變量
  • OC中并不存在類變量, 但是向類變量這個玩意,一般我們是有需求的。
  • 由于OC繼承自C, 是以我們可以使用C的方法來模拟類變量
    • 通過在類的實作檔案中使用普通的檔案作用域變量來模拟類變量。
    • 并定義類方法,來擷取與設定類變量
  • 但是,這種做法是有缺點的
    • 首先,這個變量不會被繼承(子類,要想有一個與父類一樣的靜态變量,要自己定義,并且名字不能相同)
    • 當然,也不能像java中那樣: 類名.變量 似的調用