Objective-C category (类别) 和 protocol (协议)

来源:互联网 发布:对外汉语网络教师 编辑:程序博客网 时间:2024/05/20 04:10

类别(category)


类别是oc独有的。其它语言都没有。

 类别是类的一部分,类别是类的分着写的,但是编译的时候会合在一起。 

概念,提供一种类为某个类添加方法而又不必编写子类的途径。

是objc语言中的扩展机制之一。

使用类别的目的。

将类实现部分部分离到不同的文件,提高程序可读性。

类别分解大的代码。

  1分解大的代码 。

每个类别实现类似功能的方法。

 2 ,给已有的类添加新方法,

不修改原有类的情况下,可以给类添加新方法,

注意:类别会替代原有类中同名的方法。

类别的局限

  无法向类别中添加新的实例变量,类别没有位置容纳实例变量,只能添加方法。

 

名称冲突

 类别中的方法如与原来类中已有的方法重名,将取代原有类中的同名方法,从而无法再使用原有方法。

解决名称冲突

 可以在自己的类别方法名字前增加一个前缀,以确保不发生冲名称冲突。

使用类别步骤

  声明,实现 实例化(使用)

 

协议(protocol)


协议;相当于java的接口。只提供方法,由采用协议的类去实现。

常用于两个类或模块之间进行交换数据。


非正式协议(一般不用),

正式协议

 所有实现正式协议的类,必须实现该正式协议中的所有方法。

 协议只有一个.h文件,只声明方法,不实现。

步骤:声明采用 实现 使用。

实现协议与普通类中方法实现形式一样

  在类声明的.h文件中,要包含协议的头文件,<>加上协议名,表示采用协议。

 

@optional关键字

 该指令后的方法都是可选的,即不一定要实现它,非正式协议完全可以替代了。

@required

 是默认的,该指令后面的方法,必须要实现。

协议与数据类型。

id类型的对象可以加协议限制。

表示该对象必须遵守指定的协议。 

protocol应用——复制。

浅层复制(Shallow Copy)也叫浅拷贝,该操作不会复制对象。浅拷贝后,新对象,只是指向原有对象的一个引用。例如,a如果被浅层复制给b,则b只是一个同样引用a地址的指向。

NSArray类的copy方法是浅层复制,当复制一个NSArray类的对象时,实际上复制后的对象,只是复制了原对象的一个指针,而没有复制对象本身,也就是说这个新复制的对象是原对象,指向同一个内存区域,只是同一个内容的不同名称,若其中一个对象改变了内容,那么,实际上另外一个对象的内容也改变了。

为了好理解引用c语言的方法去理解oc中的浅拷贝。


  int *p;

 p=(int *) malloc(4);

 int *p1;

 p1=p;

 free(p)


oc 中的浅拷贝:

例1,Time *time=[Time new];

Time *time1=time; 这是浅拷贝。

[time relse];


例2.A*a=[A new]

  A*b=a;

a  被浅拷贝给b。

那么b和一个同样引用a地址的指向。

[a release];

b指向的空间已经被释放,成为野指针,程序出错。


  深层复制——     深层复制(Deep Copy)也叫深拷贝,是一种会重新分配内存地址的拷贝方式。利用深拷贝,将会复制 产生一个新的对象,使用深拷贝后,对象a和b内容一样,但指针地址不一样,改变b并不影响a。


为了好理解引用c语言的方法去理解oc中的深拷贝。

int *p;

p=(int *) malloc(4);

*p=10;

int *p1=(int*)malloc(4);

*p=*p1;

free(p);

0c中的深拷贝

Time *time=[Time new];

Time *time1;

 time1=[time copy];

[time release];


深拷贝

 是一种会重新分配内存地址的拷贝方式。

利用深拷贝,将会复制产生一个新的对象。

建议使用深拷贝,少用浅拷贝。

A*a=[A new];

A *b=[a copy];

  a 如果深复制给b。

对象a和b一样,但指针地址不一样。

 a和b的值改变,都不会影响。


若自定义类要使用copy方法,必须实现NSCopying协议中的copyWithZone方法。

自定义类实现深层拷贝步骤。

采用NSCopying协议

实现NSCopying协议

调用copy方法,实现深层复制。

例:

#import <Foundation/Foundation.h>

//要想使用 copy 必须采用<NSCopying> 协议

@interface Subject : NSObject <NSCopying>

{

    //课程名称

    NSString *name;// NSString  oc 提供的字符串。

    int score;//成绩。

}

@property (copy)NSString *name;

@property int score;

-(void)print;


@end




#import "Subject.h"

@implementation Subject

@synthesize name;

@synthesize score;

//实现协议

-(id)copyWithZone:(NSZone *)zone//这个函数是协议里面的方法。

{

    

    Subject *psubject=[[Subject allocWithZone:zone]init];//初始化方法用的也是协议里面的方法。

    

    psubject.name=name;

    psubject.score=score;

    return psubject;

}

-(void)print

{

    NSLog(@"%@ %d",name,score);

}


@end


#import <Foundation/Foundation.h>

#import "Subject.h"


int main(int argc, const char * argv[])

{


    @autoreleasepool {

        

        Subject *s1=[Subject new];

        Subject *s2;

        s1.name=@"Objective-c";

        s1.score=99;

        //s1复制给s2.调用的是 -(id)copyWithZone:(NSZone *)zone 方法。

        s2=[s1 copy];

        [s1 print];

        [s2 print];

        

        [s1 release];

        [s2 release];

               

    }

    return 0;

}


原创粉丝点击