黑马程序员——ios知识整理——category、block、protocol

来源:互联网 发布:网上超市管理系统编程 编辑:程序博客网 时间:2024/06/16 02:14
-------- java培训、Android培训、.Ne培训t、ios培训、期待与您交流 --------


一、category分类/类别

category是一些方法的声明和实现,作用是在不改变源文件的前提下,给类增加新的方法或功能

category的使用步骤:

1.声明类别 ——》 2.实现类别 ——》 3.使用类别

类别的命名规范:类名+拓展方法,如『Person + countNum』

类别的接口声明与类的定义十分相似,但类别不继承父类,只需要带有一个括号,表明该类别的主要用途。


category的声明和实现:

.h文件中的格式:

@interface 需要拓展的类名(分类的名称)

需要添加的方法;

@end

.m文件中实现:

@implementation 需要拓展的类名(分类名称)

需要添加的方法{

方法的内容;

}

@end

category的使用注意事项:

1.分类只能增加方法 不能增加成员变量

2.分类中可以访问原来类中的实例变量

3.在分类中和原来的类存在同名的方法,有限调用分类中的方法

4.在多个分类中有多个同名的方法,调用最后一个编译的方法

代码示例:

假设有一个学生的类Student,具备一个run的方法,我们需要在不修改Student类源文件的前提下,给Student类追加一个study方法

Student.h

#import <Foundation/Foundation.h>@interface Student : NSObject-(void)run;@end


Student.m

#import "Student.h"@implementation Student-(void)run{        NSLog(@"Student类中声明的study方法调用");    }@end


首先我们需要按照命名规范,新建两个Student+study.h Student+study.m的文件,然后对study方法进行声明和实现

Student+study.h

#import "Student.h"@interface Student (study)-(void)study;@end


Student+study.m

#import "Student+study.h"@implementation Student (study)-(void)study{    NSLog(@"Student的分类study 新增的方法study");    }@end


现在我们在main.h中,导入头文件,调用Student类的对象方法run以及我们通过category添加的方法study

main.m


int main(int argc, const char * argv[]) { @autoreleasepool { Student *stu = [Student new]; [stu run]; [stu study]; } return 0;}
运行结果:

Student类中声明的study方法调用Student的分类study 新增的方法study


category非正式协议:Foundation框架中的类增加的类别,都称为非正式协议

category的Extension:Extension是category的一个特例,可以在延展中定义实例变量,作用是定义私有的变量和方法

Extension是不起类别名的分类


二、block块


block的基本格式:返回值类型(^块名)(参数列表)=^(参数列表){代码};


block的几种形式:无参无返回值、有参无返回值、有参有返回值以及block的typedef别名

具体代码:

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {    @autoreleasepool {                //定义一个名为myblock的块                void (^myblock)() = ^ {                    NSLog(@"这就是变量myblock的值");                };    //   注意此处的分号不可省略,跟定义一个变量的方式完全一样        //使用myblock                myblock();                //定义带参无返回值的块 sum                void (^sum)(int x,int y) = ^(int x,int y){                    NSLog(@"sum = %d",x+y);                    };        //使用sum                sum(5,6);                //定义带参有返回值的块 sum2                int (^sum2)(int x,int y) = ^(int x,int y){                        return x+y;                    };        //使用sum2                NSLog(@"sum = %d",sum2(2,3));                //定义一个无参无返回值的block新类型 newBlock        typedef void (^newBlock)();                //用newBlock定义一个块类型的变量test        newBlock test;                //将test赋值        test = ^ {            NSLog(@"block的typedef测试");        };    //  注意此处的分号        //调用test        test();        }    return 0;}


这里需要注意的是block的typedef定义的格式:

typedef 返回值类型(^新的block类型名)(参数列表);//类似函数指针的使用方式


具体的应用场景:作为函数的返回值使用

练习代码:

#import <Foundation/Foundation.h>typedef void (^myBlock) ();myBlock specialOutput(int n);void work(int n){        NSLog(@"get up");    myBlock m = specialOutput(n);    m();    NSLog(@"go sleep");}myBlock specialOutput(int n){    myBlock outPut;    switch (n) {        case 1:            outPut = ^{                NSLog(@"it's a workday");            };            break;        case 2:            outPut = ^{                NSLog(@"it's weekend! ");            };            break;        default:            break;    }    return outPut;    }int main(int argc, const char * argv[]) {    @autoreleasepool {        int m = 0;        NSLog(@"input 1 or 2");        scanf("%d",&m);        work(m);    }    return 0;}

实现的步骤总结:

1.typedef定义一个新的block类型,用其修饰函数

2.用新的block类型定义一个变量,并将其作为函数的返回值

3.在其他函数中定义一个新的block类型的变量,接收函数的返回值

4.执行block


三、protocol协议


protocol的含义:

一些方法的声明,一般写在.h的头文件中

声明的方法有两种形式:

1.必须实现的 @required (默认)

2.选择实现的 @optional

协议的作用:

让其他的类来遵守

如果一个类遵守了协议,就必须实现这个协议中定义的必须实现的方法

定义协议的格式:

@protocol 协议名<NSObject>

方法的声明;

@end

遵守协议的格式:

@interface 类名:NSObject<协议名1,协议名2...>

@end


0 0
原创粉丝点击