美文网首页
IOS之NSCoing协议实现

IOS之NSCoing协议实现

作者: 有心向往 | 来源:发表于2016-09-06 20:32 被阅读249次

近期学习NSCoding协议,发现很多小的问题,特把自己学习写的代码放到这里,供一起学习的参考一下,很简单,大神请绕过。

1. 首先定义了一Person类,对其实现NSCoding协议
 **** .h文件 ****
 #import <Foundation/Foundation.h>

 @interface Person : NSObject<NSCopying>
 @property(nonatomic,strong) NSString * name;
 @property(nonatomic,strong) NSString * gender;
 @property(nonatomic,strong) NSString * address;
 @property(nonatomic) NSUInteger age;
 -(instancetype)initWithName:(NSString*)name gender:(NSString*)gender address:(NSString*)adderss age:(NSUInteger)age;
 +(instancetype)  FactoryWithName:(NSString*)name gender:(NSString*)gender address:(NSString*)adderss age:(NSUInteger)age;
 -(void)function;

**** .m文件 ****
#import "Person.h"
@implementation Person
-(instancetype)initWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age{
    if (self = [super init]) {
        _name = name;
        _gender = gender;
        _address = adderss;
        _age = age;
    }
    return self;

}
+(instancetype)FactoryWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age{
    return [[self alloc]initWithName:name gender:gender address:adderss age:age];
}
 -(void)function{
    NSLog(@"我是一个人");

}
 //为了打印对象信息方便,从写了description方法
-(NSString*)description{
    return [NSString stringWithFormat:@"name:%@  gender:%@  age:%lu address:%@",self.name,self.gender,(unsigned long)self.age,self.address];

}
//这里对NSCoding协议进行实现,由于返回一个对象,就需要创建一个对象并返回,
//这里使用[self class]获取类,而不是直接使用Person类进行创建,是为了它的
//子类实现协议时候,调用父类的方法,返回的是子类的对象而不是父类的对象。如果
//子类没有增加实例变量还好,如多增加,由于返回的是父类对象,由于不存在子类
//添加的属性,调用不存在或者为不存在的属性赋值会出错。下面子类再次说明本问题。
  
-(instancetype)copyWithZone:(NSZone *)zone{
        return [[[self class] allocWithZone:zone] initWithName:[_name copy] gender:[_gender copy] address:[_address copy] age:_age];

}
@end
2.继承自Person类创建Student
**** .h文件  ****
#import "Person.h"
@interface Student : Person
@property(nonatomic) NSUInteger score;
-(instancetype)initWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age score:(NSUInteger)score;
+(instancetype)factoryWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age score:(NSUInteger)score;

@end

**** .m文件 ****
#import "Student.h"

@implementation Student
-(instancetype)initWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age score:(NSUInteger)score{
    if (self = [super initWithName:name gender:gender address:adderss age:age]) {
        _score = score;
    }
    return self;
}
+(instancetype)factoryWithName:(NSString *)name gender:(NSString *)gender address:(NSString *)adderss age:(NSUInteger)age score:(NSUInteger)score{
    return [[self alloc]initWithName:name gender:gender address:adderss age:age score:score];
    
}
-(void)function{
    NSLog(@"我是一名学生,我考了%lu",(unsigned long)self.score);
}
//这时候实现NSCoding协议可以继承父类的协议方法,也可以像父类那样重新
//写。如多继承父类的,如[super copyWithZone:zone],由于父类的方法使用的
//是[self class],这样[self class]结果便是Student类,[super copyWithZone:zone]
//结果便是Student的对象。
-(instancetype)copyWithZone:(NSZone *)zone{
    Student* student = [super copyWithZone:zone];
    student.score = _score;
    return student;
}
-(NSString*)description{
    return [[super description] stringByAppendingString:[NSString stringWithFormat:@"  score:%lu",(unsigned long)_score]];
}
@end
3.我们创建一个School类,里面有自定义Student类,然后遵循NSCoding协议
**** .h文件  ****
#import <Foundation/Foundation.h>
#import "Student.h"
@interface School : NSObject<NSCopying>
@property(nonatomic,strong) Student * student;
@property(nonatomic,strong) NSString * address;
-(instancetype)initWithAddress:(NSString*)address student:(Student*)student;
+(instancetype)factoryWithAddress:(NSString*)address  student:(Student*)student;
@end

**** .m文件  ****
#import "School.h"
@implementation School
-(instancetype)initWithAddress:(NSString *)address student:(Student *)student{
    if (self = [super init]) {
        _address = address;
        _student = student;
    }
    return self;
}
+(instancetype)factoryWithAddress:(NSString *)address  student:(Student *)student{
    return [[self alloc]initWithAddress:address student:student];
}
//这个时候由于我们的学生已经实现了本NSCoping协议,可以直接使用copy协议,
//深复制出一样的一个对象,原来对象修改,不影响复制出来的对象
-(instancetype)copyWithZone:(NSZone *)zone{
    return [[[self class] allocWithZone:zone]initWithAddress:[_address copy]  student:[_student copy]];
    
}
-(NSString*)description{
    NSString* teacher = _teacher.description;
    NSString* student = _student.description;
    return [NSString stringWithFormat:@"\naddress:%@\nteacher:%@\nstudent:%@",_address,teacher,student];
}
@end

代码实例很简单,逻辑也是很简单的,需要注意 的地方在代码里都有注释,还有NSMutableCoping协议没有说,这个协议适合用在数组,字典等集合类型,看复制出来的对象是否可以变化。
-主要注意点
  1. [self class]代替直接写类
  2. [[[self class] allocWithZone:zone]initWithAddress:[_address copy] student:[_student copy]]
    在协议里复制属性时候,使用本身的copy方法,不然会出现,复制出来的实例变量会跟随复制前对象的实例变量改变而改变。就是说一定要深复制属性,不是只复制实例变量的指针。

如果有错误的地方请指正,互相学习进步

相关文章

网友评论

      本文标题:IOS之NSCoing协议实现

      本文链接:https://www.haomeiwen.com/subject/zindettx.html