协议

1.实现协议

  • 正式协议是一个命名的方法列表(与非正式协议一样)
  • 正式协议显式的要求采取协议(与非正式协议步一样)
  • 采取协议的办法是在@interface声明中列出协议的名称;
  • 采取协议意味着承诺实现协议的所有方法(正式协议与java的接口一样)

(一)声明协议

@protocol NSCopying

-(id)copyWithZone:(NSZone *)zone;

@end
@protocol NSCoding

-(void)encodeWithCoder:(NSCoder *)aCoder;
-(id)initWithCoder:(NSCoder *)aDecoder;

@end


理解:

@protocol 告诉编译器:下面将是一个新的正式协议。

@protocol  之后是协议名称,协议名称唯一

然后是方法声明列表,协议的每个采用者都必须实现这些方法。

@end 结束符

使用协议步引入新的实例变量。


(二)采用协议

@interface Car : NSObject<NSCoding,NSCopying> 
{
    //实例变量
    
}
//方法
@end


理解:

采用某个协议,在类的声明中列出该协议的名称,并用 < >  将协议名称括起来。

多个协议只见用逗号隔开,顺序步影响。

(三)实现协议


采用该协议的类的实现文件中,实现协议的声明的 v方法。


Ps:

1).可以使用一下方法来检查一个对象是否遵守某个协议


if(![receiver conformsToProtocol:@protocol(MyXMLSupport)])

2).如果定义了自己的协议,并不意味着自己去实现它,但告诉其他程序员,如果要使用这项协议,则必须实现这些方法。

3).协议中的方法可从超累中继承,但并不意味着对于该子类,这些方法得到了正确的实现。当子类新增数据成员时???


2.常用协议

@protocol NSCopying

@protocol NSCoding

把对象编码为数据块,并保存在磁盘中。

能将数据块读回到内存中。还能机遇保存的数据创建新的对象。

3.NSCopying协议


实质:

实现一个无实例变量类的复制,

即实现copy协议中的copyWithZone方法;

里程1:Engine类的复制

@interface Engine : NSObject<NSCopying> 
{
    //实例变量
    
}
//方法
@end


因为用了NSCopying协议,必须实现它的方法。


@implementation Engine

-(id)copyWithZone:(NSZone *)zone
{
    Engine *engineCopy;
    
    engineCopy = [[[self class]allocWithZone:zone]init];
    /**
     实现过程:
     step1:[self class] 获取self对象所属的类。//向获取类就要发送class方法
     step2:[[self class]allocWithZone:zone] 向该类发allocWithZone:zone消息,以分配内存并创建该类的一个新对象。//
allocWithZone:zone使一个类消息
step3: 向心对象发送init消息,以使其初始化。 **/ return engineCopy;}@end


 engineCopy = [[Engine allocWithZone:zone]init];
在子类继承的时候会出错。




协议分为声明/使用/实现。可能三个同时出现,可能仅出现最后一个。

4.深拷贝和浅拷贝

浅层复制 (shallow copy)不复制引用对象,新复制的对象只指向现有的引用对象。

深层复制(deep copy)将复制所有引用的对象。

1).遵守NSCopying协议的类才可以发送copy消息;

2).遵守NSMutableCopying协议的类才可以发送mutablecopy消息

3).一个类没有遵守上述两个协议,而发送copy,mutablecopy,会发生异常。


里程2:Tire类的复制


//有实例变量,切其子类又新添加实例变量的类的复制
@interface Tire : NSObject<NSCopying> {

    float pressure;
    float threadDepth;
}
@property float pressure;
@property float threadDepth;

-(id)initWithPressure:(float)pressure;
-(id)initWiththreadDepth:(float)threadDepth;
-(id)initWithPressure:(float)pressure WiththreadDepth:(float)threadDepth;
@end
实现文件:

@implementation Tire

-(id)copyWithZone:(NSZone *)zone
{
    Tire *tireCopy;
    tireCopy = [[[self class]allocWithZone:zone]initWithPressure:20.0f WiththreadDepth:20.0f];
    /**
     实现过程:
     step1:[self class] 获取self对象所属的类。
     step2:[[self class]allocWithZone:zone] 向该类发allocWithZone:zone消息,以分配内存并创建该类的一个新对象。
     step3:
     向心对象发送initWithPressure: WiththreadDepth:消息,以使其初始化。也可以使用见大init。
     **/
    return tireCopy;
}

@end
zone 来自方法参数,pressure和threaddepth 来自与类的成员变量。

里程4:

allweather的复制


@interface allWeathRadical : Tire {
    float rain;
    float snow;
}
@property float rain;
@property float snow;
@end

@implementation allWeathRadical

-(id)copyWithZone:(NSZone *)zone
{
    allWeathRadical *tireCopy;
    tireCopy = [super copyWithZone:zone];
    [tireCopy setRain:rain];
    [tireCopy setSnow:snow];
    /**
     step1:tireCopy = [super copyWithZone:zone];
     调用超累的copyWithZone:zone方法
     
     step2:
     [tireCopy setRain:rain];
     [tireCopy setSnow:snow];
     调用访问器方法处理新增的实例变量
     step3:
     若子类无新增的实例变量,则可直接使用超类的协议方法,若新增,则需重写初始化方法。
     **/
    return tireCopy;
}

里程4.

实现car类的复制

实质:数据成员是指向oc对象的指针,调用协议方法,copy操作后内存管理方法。



在默认情况下,NSObject没有遵守这两个协议,但copy,mutable copy方法是nsobject定义的。

若要自定义copy,必须遵守nscopying协议,并实现copywithzone:方法

mutablecopy同上

遵守nscopying协议的基本是基础核心类,如nsstring,nsnumber;


copy后,返回一个新对象,程序员要负责释放,原先被拷贝对象的retaincount +1,所以不需要释放。


copy后,返回的是不能修改的对象,mutable copy返回的对象可能是可以修改的。


copy复制一个步可变对象。而mutable copy复制一个可变对象。


代码实例1:对非容器类对象的拷贝


1)。对一个不可变对象的复制,copy是指针复制,即浅拷贝;mutablecopy则是对象复制,即深拷贝。(实例1)

2)。对可变对象复制,都是深拷贝,但copy复制返回的对象是不可变的。(实例2)

代码实例2:对容器类本身

上面的结论也适用。

对容器而言,其元素对象事中是指针复制。如要元素对象的为对象复制,就需要实现深拷贝。



理解协议三步骤:声明协议/实现协议/使用协议

了解常用协议

理解深复制,浅复制

利用nscopying协议实现自定义objc对象的深复制。

了解nscopying协议对基础核心类对象的深/浅复制。





你可能感兴趣的:(java,Class,float,interface,编译器,磁盘)