黑马程序员——Objective--C笔记Category、block

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

分类(Category)

一.分类(Category)

1.Category有很多种翻译: 分类\类别\类目 (一般叫分类),也就是一些方法的声明和实现

2.作用:在不修改类的源代码的前提下,给类增加新的功能

3.使用的步骤:

此处是声明一个类

@interface   Person :NSObject

@end

1)声明一个分类

格式:@interface  待扩展的类名(分类的名称)

            @end

注意:类别的命名规则:类名+扩展方法,如"Person+base"。类别的接口声明与类的定义十分相似,但类别不继承父类,只需要带有一个括号,表明该类别的主要用途。 

例:@interface   Person  (base)

        -(void)eat;    //吃的方法

        -(void)run;   //跑方法

       @end

2)实现这个分类:

  格式:@implementation    带扩展的类名  (分类名称)

             @end

例:Person+base   类别实现

       @implementation     Person  (base)

         -(void)eat{

              NSLog(@"人正在吃东西");

      }

        -(void)run{

             NSLog(@"人在跑步");

     }

     @end

3.使用分类中的方法和使用类中原有的对象一样

 例:Person  *p=[ Person     new ];

        [p   eat];

4.调用类别中的方法与一般成员方法调用形式完全一样,需要包含类别的头文件

5.分类的使用注意:

1).在分类的声明中不能声明实例变量,不能定义实例变量,也不能使用@property

2).在分类的方法中,可以访问类中的实例变量

3).在分类中存在和类同名的方法,优先访问的是分类的方法

4).当在多个类别中有同名的方法的时候,执行的最后编译的那个类别的同名方法

    分类   >    原类

    最后编译的分类    >   其他的分类

例:统计字符串中阿拉伯数字的个数

NSString+countNum.h


NSString+countNum.m 


main.m

6. 非正式协议就是给NSObject类创建的类目(分类)又叫做非正式协议, 非正式协议一般不需要进行实现,一般在子类中进行方法的重写。

二. 分类的延展

1.延展类别又称为扩展(Extension ),延展是一个特殊的分类

2.特点:1).可以在延展中定义实例变量

                2).不能使用implementation    类名()实现类别的方法

3.延展实现方法的私有

1).通过延展来实现方法的私有,延展的头文件独立。这种方法不能实现真正的方法私有,当在别的文件中引入延展的头文件,那么在这个文件中        定义的类的对象就可以直接调用在延展中定义所谓私有的方法 

2).实现延展的方式是延展没有独立的头文件,在类的实现文件.m中声明和实现延展,这种方法可以很好的实现方法的私有,因为在OC中是不能引       入.m的文件的 

3).实现方法私有的方式是在.m文件中得@implementation中直接实现在@interface中没有声明的方法,这样也可以很好的实现方法的私有      

4.类别也扩展的区别

1).类别中只能添加方法,扩展中不仅可以增加方法还可以增加实例变量,只是该实例变量默认为私有的(作用范围只在自己类,而不是子类和其他的地     方)

2).类扩展中声明的方法没被实现,编译器会报错,但是类别中的方法没有实现是不会有任何警告的,这是因为类扩展是在编译阶段被添加到类中,类别      则是在运行的时候被添加到类中

3).类扩展不能像类别那样拥有独立的实现部分,类扩展所有的声明的方法必须依托对应类的实现来实现

4).定义在.m文件中的类扩展方法为私有的,定义在.h文件中的类扩展方法为公有,类扩展是在.m文件中声明私有方法的非常好的方式

block 

一.block 

1.block对象是一个C级别的语法和运行机制。它与标准的C函数类似,不同之处在于,它除了有可执行代码以外,它还包含了与堆、栈内存绑定的变量。因此,block对象包含着一组状态数据,这些数据在程序执行时用于对行为产生影响。 

2.block定义格式:

1).有参数有返回值

返回值类型  (^变量名)(参数类型及个数) =^(行参列表){

                          代码块语句;

                         return;

};

例:int (^ block1) (int ,int)=^(int x ,int y){

              return x+y;

        };

2).有参无返回值

void(^变量名)(参数类型及个数) =^(行参列表){

             代码块语句;

};

例:void(^block2) (int ,int )=^(int a,  int b){

            NSLog(@"%d",a+b);

         };

3).无参无返回值

void(^变量名) ( ) =^ ( ){

             代码块语句;

};

例:void(^block3) ( )=^(){

            NSLog(@"xxxx");

      };

4).给变量重新赋值:

例:block1=^(int x ,  int y){

           return x*y;

      };

2.利用typedef定义block类型可以利用这种类型来定义block变量了 

格式:typedef  返回值类型(^变量名) (参数类型列表);

例:给有参有返回值的block类型定义新的别名

        typedef  int (^NewType1)  (int  ,int );

        NewType1 n =^(int a,  int b){

               return  a+b;

       };

3.block访问外部变量

当定义block的时候,block会把外部变量以const的方式复制一份,存放到block的所在内存堆区中,在默认情况下,在block内部中无法修改外部的变量,block内部也可以定义和block外部的同名的变量(局部变量),此时局部变量会暂时屏蔽外部变量的作用域 


4.给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。 


5.block作为函数的返回值

1.使用typedef定义一个新的类型

typedef  int(^new Type)(int  num1,int num2);

2.使用新类型作为函数的返回值

new Type  test( ){

        new Type  n= ^ (int  x,  int y){

                return  x+y;

        };

                return  n;

}

3.定义变量接受函数的返回值

4.调用block

new Type  w   =test();

NSLog(@"w=%d",w(34,76));

6.block变量用作方法的参数的时候 ,最好把参数类型列表部分加上 具体的形参名 

例:void test (^int (int   num1, int  num2)){

}

int  main(  ){

        test (^int (int   num1, int  num2){

                  return num1+num2;

};

}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值