分類 協議 延展 block

OC加強day03

分類的簡單使用
- 什麼是分類
- 當一個類包含了非誠多的術語不同範疇的方法的時候 我們通常將這個類分爲多個文件來實現,其中一個類叫主類/本類其餘的叫分類
- 有了分類之後 一個類 = 所有分類 + 本類
- 如何添加分類
- newFile–> 選中OC File–>選擇category—>填寫分類名,本類名
- 分類的聲明

   @interface 本類名 (分類名)

    @end

    @implementation 本類名 (分類名)

    @end

* 分類的使用注意*
- 在分類中不能寫屬性,只能寫方法的聲明和實現
- 在分類中用@property也是可以的
- 但是即使使用了 @property 也不會生成屬性,只會生成getter和getter方法的聲明(不包含實現)
- 在分類中可不可以訪問本類的中的屬性? 可以
- 在分類中 不能直接訪問本類中的真私有屬性,但是通過getter各setter方法來訪問本類的真私有屬性
- 本類中的方法和本類的方法能不能同名? 可以
- 這個時候 不管有沒有引入分類 都會調用分類的方法
- 如果多個分類中有同名的方法 只會調用最後邊編譯的那個分類中的方法
- 怎麼看那個分類是最後編譯的?
選中項目—>選中Target—>Build Phase–>編譯源(Compile Source)–>在此修改順序即可

  • 總結: 分類的使用場景
    • 團隊開發對個人共同寫一個類的時候
    • 當一個類方法非常多的 功能複雜的時候

非正式協議
- 其實非正式協議就是一個分類,是爲系統類添加的分類

延展的基本使用
- 延展是什麼?
- 一個特殊的分類:
- 是一個匿名的分類(就是一個分類沒有名字)
- 在延展中可以有屬性,但是隻有方法的聲明,而沒有方法的實現(方法的實現在本類的.m文件中)
- 如何寫一個延展

@interface 本類名 () // 小括號中什麼都不寫 就是延展
@end
  • 注意:延展沒有實現,和本類共同用一個實現
  • 延展的使用注意
    • 普通的分類(有名字):
      • 不能寫屬性,可以寫方法的聲明和實現。
      • 普通分類中可以使用@property,只會生成方法的聲明
    • 延展(沒有名字)
      • 可以寫屬性,可以有方法的聲明,延展的實現在本類中
      • 延展中可以使用@property,會有屬性也會有方法的聲明和實現

延展的基本使用
- 延展的作用: 生成私有的@property和私有方法
- @property 會生成屬性,方法的聲明,方法實現
- 什麼是私有的@property? 就是生成的屬性,方法的聲明和實現都不讓外界訪問
- 怎麼辦?
- 在.m中 可以寫一個延展,然後把@property 寫到延展裏 這樣生成的_屬性名,getter和setter方法的聲明都在.m文件中
- 延展如何使用?
- 大部分的情況下,延展都會寫在本類的.m文件中,而且是寫到最上面
- 然後可以在延展中寫屬性的方法,這些屬性和方法都是私有的成員
- 總之:
- 延展就是用來私有化成員的,只要你想寫一個私有的成員(屬性,方法)
- 寫到延展中

block變量的聲明
- block是一個數據類型,它的變量可以存 一段符合要求的代碼
- block變量的聲明:

  返回值類型 (^變量名)(參數列表);
  xxx (^ttt)(xxx a,ooo b);
  聲明瞭一個block類型的變量, 變量名字叫做ttt;
  ttt可以儲存  返回值類型是 xxx  有一個xxx類型的參數  一個ooo類型的參數

block變量賦值初始化
- 寫一個block代碼塊的格式

 ^返回值類型(參數列表){
  代碼;
 }

- 寫一個代碼塊 求2個整數的和

 ^int(int num1,int num2){
        //代碼功能就是求和
//        return num1+num2;
        int num3 = num1 + num2;
        return num3;
    };
    寫一個代碼塊 求2個整數的最大值
    ^int(int num1,int num2){
        //代碼塊 求num1,和num2中的最大值
        int max = num1 > num2 ? num1 : num2;
        return max;
    };

3.保存上面的2個代碼塊
   3.1>//第一種
    int (^blockSum)(int num1,int num2);//定義了一個變量
    blockSum =   ^int(int num1,int num2){
        //代碼功能就是求和
        //        return num1+num2;
        int num3 = num1 + num2;
        return num3;
    };
    //第二種
    int (^blockSum)(int num1,int num2) =  ^int(int num1,int num2){
            //代碼功能就是求和
            //        return num1+num2;
            int num3 = num1 + num2;
            return num3;
        };
    3.2>//第一種
        int (^blockMax)(int num1,int num2);//定義了一個變量
        blockMax =  ^int(int num1,int num2){
            //代碼塊 求num1,和num2中的最大值
            int max = num1 > num2 ? num1 : num2;
            return max;
        };
        //第二種
        int (^blockMax)(int num1,int num2) = ^int(int num1,int num2){
            //代碼塊 求num1,和num2中的最大值
            int max = num1 > num2 ? num1 : num2;
            return max;
        };
  • 執行block變量中的代碼
    • 格式:
      • block變量名字(實參列表)
      • 需要參數就穿進去
      • 如果有返回值 就接收

block 使用 typedef的簡化 定義
- typedef 的作用是?
- 爲一個已經存在的數據類型,起一個 別名
- 使用typedef簡化block的定義
- typedef的基本使用

typedef long int Lint;
int nums1[4];//int[4] nums1;
int nums2[4];//int[4] nums2;
typedef int NUM[4];
NUM nums3;//等價於 int nums3[4];

- typedef簡化block的定義
“`
void (^blockName)(int,int);
//void (^)(int,int) blockName;==>XXX a;
語法格式:
// typedef void (^)(int,int) NewType;
typedef 返回值類型 (^新類型名字)(參數列表);
typedef void (^NewType)(int,int);
這個NewType就是新類型的名字
就可以通過NewType 來定義block變量
NewType block1,block2;


**block訪問外部變量的問題**
- block代碼段內部,可以定義和玩不變量名字相同的變量
- 在block代碼段的內部
    - 可以訪問外部的全局變量和局部變量的值
    - 可以修改全局變量和自己的局部變量的值 但是不能修改外部局部變量的值
    - 如果非要修改 就子啊外部的局部變量的值 定義的時候前面加上 __block修飾

**block作爲函數的參數**
- block作爲函數的參數的寫法

void test(返回值類型 (^變量名)(參數列表1,參數列表2))
{

}
//第二種
typedef void (^NewType)(int num1,int num2);
void test(NewType block1)
{

}

- 在函數內部如何執行block代碼

typedef void(^NewType)(int num1, int num2)
void tese(NewType block1)
{
block1(有參數寫參數 沒參數拉倒)
//有返回值就接收
}

- 調用這個函數的終極方法
        1>定義一個block變量 給他賦值
    NewType block2 = ^void(int num1,int num2){
            int num3 = num1 + num2;
            NSLog(@"num3 = %d",num3);
            };
    2>調用函數
        test(block2);
    3>終極版
        test(^void(int num1,int num2){
            int num3 = num1 + num2;
            NSLog(@"num3 = %d",num3);
        });//有一個小技巧,調用函數的時候         如果需要傳遞代碼塊,只需要敲回車鍵,自動添加代碼塊的格式

- "注意:定義block變量的時候,block內的代碼不會執行
    "block內的代碼只有在調用block的時候才執行

4.例子:
1>寫一個函數模擬 下載數據 解析數據 並且調用視頻播放器播放
2>寫一個函數模擬 下載音頻 解析數據 並且調用音樂播放器播放

import

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