关闭

分类 协议 延展 block

标签: class分类协议延展block
386人阅读 评论(0) 收藏 举报
分类:

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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7273次
    • 积分:329
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    文章存档