1. 分类 Category的使用流程
  Category的作用是用来扩展类,在不修改以前的源代码的情况下
  Category有很多翻译:分类 \ 类别 \ 类目 (一般叫做分类)

  分类的作用
  1.一个庞大的类可以分模块来开发,如:C#中的partial关键字,对类进行分多个类
  2.一个庞大的类可以有多个人来编写,更有利于团队合作
  3.在不修改原有的类的基础上增加新的方法
  
  使用分类的目的
  1) 对现有的类进行扩展
     比如:你可以扩展Cocoa touch框架中的类,你在类别中增加的方法被子类继承,而且在运行时跟其他的方法没有区别
 
  2) 作为子类的替代手段
     不需要定义和使用一个子类,你可以通过类别直接向已有的类里增加方法
 
  3) 对类中的方法归类
     利用category把一个庞大的类划分为多个小块进行开发,从而更好的对类中的方法进行更新和维护
 
 
 分类的命名规范
 类名 + 扩展方法名
 例如:为Person类扩展一个统计个数方法,那么名称为
 Person+Statistic.h
 Person+Statistic.m
 分类的接口声明与定义十分相似,旦分类不继承父类,只需要带有一个括号,表明该分类的主要用途
 
 使用格式   
 @interface 待扩展的类名 (分类的名称)
 @end
 
 例如:为Person类扩展一个walk方法
 1.文件名(头文件)  Person+walk.h
@interface Person (walk)
@end

 2.文件名(源文件)  Person+walk.m
    @implementation Person (walk)
@end
 
 调用时,跟非Category类一样的调用,导入#import "Person+walk.h"

 Category使用注意事项
 1.分类只能增加方法,不能增加成员变量
 2.分类可以访问原来类的成员变量
 3.如果分类和原来的类出现同名的方法,优先调用分类中的方法,原来类中的方法会被忽略
 4.如果多个分类中都有一个相同方法,那么以最后编译的那个文件为主,
   查看步骤:选中项目 -> 选中Target -> 选中Build Phases -> 选中Compile Sources -> 查看最后一个编译的文件,如果需要可以上下拖动文件
  

 
 
 2. 分类(Category) 非正式协议
    显然这个名词是相对于正式协议而言的,在解释非正式协议之前,先引用两段话:
    非正式协议通常定义为NSObject的类别
    类别接口中指定的方法可能会或者可能不会被矿建类实际的实现,而是被子类重写

    所谓的非正式协议就是类别,即凡是NSObject类或其子类Foundation框架的类别,都是非正式协议

    非正式协议就是类别,类别可以说有两种:
   一种是对普通类进行扩展类别
   一种是对NSObject类或者其子类Foundation框架的类进行扩展类别  
   第二种既是非正式协议

   示例代码1:对NSObject类进行扩展

<span style="font-size:18px;">@interface NSObject (getObjCount)
//那么所有继承自NSObject的类,都可以继承该类的该方法
-(void)getObjCount;
@end
@implementation NSObject (getObjCount)
 -(void)getObjCount{
    NSLog(@"所有继承NSObject的类都可以使用这个方法,该类可以说就是非正式协议");
}
@end

实例代码2:对NSString类进行扩展
@interface NSString (getNumber)
-(void)getNumber;
@end
@implementation NSString (getNumber)
-(void)getNumber{
    NSLog(@"对NSString类(它是Foundation框架的类)进行扩展类别就是非正式协议");
}
@end</span>







3. 分类   延展


   延展类别又称为扩展(Extension)


   Extension是Category的一个特例


   其名字为匿名(为空),并且新添加的方法一定要予以实现。(Category没有这个限制)



   1.延展的文件格式


     延展文件名(头文件可以独立,源文件与原类共用) 


     Person_walk.h  walk是延展的名称


     @interface 要延展的类名 ()




使用注意事项:


1.可以为延展的类添加成员变量


2.延展的类没有实现文件,而实现文件和原类的源文件共用


3.一般用作私有方法或者变量时,在同一个类中创建类的延展



   实例1:


   //类的延展


  

<span style="font-size:14px;"> </span><span style="font-size:18px;"> @interface Person ()
   //私有属性变量和方法
   @property (nonatomic,assign) int age;
   -(void)run;//该run是一个相对的私有方法,OC中没有绝对的私有方法
   @end
   
   //原类
   @interface Person : NSObject
   @end
   
   //类的实现(源文件)
   @implementation Person
   -(void)run{
<span style="white-space: pre;">	</span>NSLog(@"Person类的延展");
   }
   @end</span>






4. block的概念和基本使用


   Block类型是一个C级别的语法和运行机制,它与标准的C函数类似,不同之处在于,


   它除了有可执行代码意外,它还包含了与堆,栈内存绑定的变量,因此,Block对象包含


   一组状态数据,这些数据在程序执行时用于对行为产生影响


   


   IOS 5.0之后增加了block




   block兼容C , C++  和  Objective-C




   C语言的面向过程的语言,所有的操作都是通过函数来执行的




   函数有一个代码段


   block也有是一个代码段


   


   用^操作符来声明一个Block变量,并指明Block述句的开始,Block的主体部分包含在{}内


   像C语法一样 一个";"表示语句的结束


   


   int (^myBlock)(int) = ^(int num) { return 0; }


 


   1.有参有返回值


   2.有参无返回值


   3.无参有返回值


   4.无参无返回值


   


   用法有点类似函数指针,又有点类似lambda表达式


   


   格式: 


   void (^block变量名)(参数类型和个数) = ^(形参){


//具体代码块


   };


   


   实例代码:


   

int main(){
     @autoreleasepool{
<span >	</span>//1.无参无返回值,形参的括号可以省略
   <span >	</span>void (^myBlock1)() = ^(){ 
<span >		</span>NSLog(@"无参无返回值!");
<span >	</span>};
        //调用
<span >	</span>myBlock1();
   
<span >	</span>//2.有参无返回值 
<span >	</span>void (^myBlock2)(int) = ^(int a){
<span >	</span>       NSLog(@"有参数无返回值,实参a=%d",a);
<span >	</span>};
<span >	</span>//调用
<span >	</span>myBlock2(10);

<span >	</span>//3.有参有返回值
<span >	</span>int (^myBlock3)(int,int) = ^(int a,int b){
<span >	</span>NSLog(@"有参有返回值!");
<span >		</span>return a + b;
<span >	</span>};
<span >	</span>myBlock3(10,20);
<span >	</span>//也可以直接给变量重新赋值,动态的赋值
<span >	</span>myBlock3 = ^(int a,int b){
<span >		</span>return a * b;
<span >	</span>};
<span >	</span>myBlock3(10,20);

<span >	</span>//4.无参有返回值
<span >	</span>int (^myBlock4)() = ^(){
<span >		</span>NSLog(@"无参有返回值!");
<span >		</span>return 200;
<span >	</span>};
<span >	</span>myBlock4();
     }
     return 0;
}