A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

一,分类的概念及使用流程:
1,什么是分类?
    分类,就是Category,是OC特有的语法;
    Category有很多种翻译: 分类 \ 类别 \ 类目 (一般叫分类)


2,分类的作用:
    (1),对现有类进行扩展;
    (2),在不修改原有的类的基础上增加新的方法;


3,分类的使用流程:
    先声明类别--->实现类别--->使用类别


二,分类的声明和实现:
1,分类的声明:
    (1),分类的声明格式:
        @interface 待扩展的类名 (分类的名称)

        @end

    (2),在.h文件中,声明分类:
        @interface ClassName (CategoryName)
        //只能在分类中添加方法
            NewMethod;
        //不能在分类中添加成员变量
        @end

    (3),分类声明格式的说明:
        1)新添加的方法必须写在 @interface 与@end之间
        2)ClassName 现有类的类名
        3)CategoryName 待声明的类别名称
        4)NewMethod 新添加的方法


2,分类的实现:
    (1),分类的实现格式:
            @implementation 待扩展的类 (分类的名称)

            @end

    (2),在.m文件中实现分类:
            @implementation ClassName(CategoryName)
                NewMethod
            @end

    (3),分类实现格式说明:
            1)新方法的实现必须写在@implementation与@end之间
            2)ClassName 现有类的类名
            3)CategoryName 待声明的类别名称
            4)NewMethod 新添加的方法的实现



3,分类的使用:
    (1),导入分类的头文件;
    (2),使用类别中的方法,和使用一般成员方法一样;需要创建对象,然后用[]调用类别中的方法即可;



三,分类的使用注意事项:
    1,分类只能增加方法, 不能增加成员变量、也不能使用@property;*****
    2,分类可以访问原来类中的成员变量;
    3,如果分类和原来类出现同名的方法, 优先调用分类中的方法, 原来类中的方法会被忽略;*****
    4,如果多个分类中有同名的方法,执行哪个分类的方法,取决于编译的顺序,最后编译的那个分类中的方法会执行;



四,非正式协议:
    1,非正式协议就是类别,即凡是NSObject或其Foundation框架中的子类的类别,都是非正式协议。



五,延展:
    1,什么是延展?
        延展又称为扩展(Extension),是Category的一个特例,是匿名的一个分类;

    2,延展的声明:
        //延展的声明                     //分类的声明
        @interface Student ()           @interface Student(Creation)
        @end                            @end

    3,延展的特点:
        (1),可以在延展中,定义实例变量;
        (2),没有自己的实现文件,只能在当前类中实现;


    4,延展的意义:
        (1),就是定义私有的方法和私有变量;(一般都在 .m 文件中)



六,block的简单用法:

1,block的基本用法:
    1) block最简单形式 :
        定义格式:
            void (^block名)() = ^{代码块;}

        使用格式:
            block名();

        例如:
            定义一个block:
                void (^myBlock)() = ^ {
                    NSLog(@"hello");
                };

            调用block:
                myBlock();


    2),带有参数的block的定义和使用:
        定义格式:
            void (^block名称)(参数列表)
                = ^ (参数列表) { // 代码实现; }



        例如:
            //定义有参数的block
            void (^sumBlock)(int, int) = ^ (int x, int y) {
                 NSLog(@"%d", x + y);
             };
             //调用block
             sumBlock(10, 20);
            
                    
                    
    3),带有参数和返回值的block
        定义格式:
               返回类型 (^block名称)(参数列表)
                  = ^ 返回类型 (参数列表) { // 代码实现; }
            
                 
                     
         例如:
              //定义有返回值和参数的block
               int (^sumBlock2)(int, int) = ^ int (int a, int b) {
                     return a + b;
                };

                     
               //调用有返回值的block
                NSLog(@"%d", sumBlock2(4, 8));
                     
              
                     
//--------------------------下午-----------------------------
                     
一,typedef 在block中的使用:
     1,函数指针回顾:
          typedef int (*NewType)(int x,int y);
          NewType f1,f2,f3; //f1实际类型 int (*f1)(int x,int y);
                     
                  
                  
     2,block的typedef
          格式:
             typedef  返回值类型 (^block变量名)(参数类型列表);
                     
          例如:
             typedef void (^newType)();
                     
             //用新的类型定义block变量
              newType t1;
              t1 = ^{
                    NSLog(@"我是使用newType定义出来的变量t1的值");
                };
            //使用block
              t1();
        
                     
                     
                     
二,block访问外部变量:
       1,在block内部可以访问block外部的局部变量;当定义block的时候,block会把外部变量以const的方式复制一份,存放到block的所在的内存中.

                void test(){
                    int m = 10;
                    
                    void (^myBlock)()=^{
                        
                        //block会把外部变量m 以const的方式复制一份,到自己的内存中,并且不能修改
                        
                       };
                          
                }
                     
                     
       2,默认情况下,block内部不能修改外部的局部变量;如果非要修改,给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。
                     
                      void test(){
                          __block int m = 10;
                          void (^myBlock)()=^{
                              
                              //如果非要在这里修改m的值,需要给m加上__block关键字
                              m = 100;
                              //这样可以理解为,block不在以const的方式拷贝m的变量到自己的内存中
                          };
                          
                      }
                     
                     
                     
        3,如果在block中将m的值改变了之后,后面在使用m的时候,使用的都是block中的m;
                     
      
                     
                     

练习:
                     
三,block作为函数的参数传递;
                     
四,block作为函数的返回值;
                1,使用typedef定义一个新的类型;
                      typedef int(^newType2)(int ,int );
                     
                2, 用新定义的类型作为函数的返回值
                      newType2 test2(){
                          
                          //返回一个特殊的"值" 这个值是一个有返回值,有两个参数的的代码块
                          return ^(int a,int b){
                              
                              return  a+b;
                          };
                          
                      }
                     
                     
                3,定义block变量接收 函数返回的结果
                       newType2 n2 = test2();
                     
                     
                4,执行block
                      int s =  n2(23,12);
                      NSLog(@"s = %d",s);
                     
                     
                     
                     
五,block的使用技巧:
   1,inlineBlock  block助记符;
   2,自定义代码块;
   3,声明标准的block代码;
                     
                     
                     
                     
                     
                     
                     
                     

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马