Objective-C中的<NSCopying>协议
2018-01-17 本文已影响29人
恩莱客
先给出一个demo案例:
model类.h文件:
#import <Foundation/Foundation.h>
@interface LQUserModel : NSObject
@property (nonatomic, copy, readonly) NSString *userName;
@property (nonatomic, assign, readonly) NSUInteger age;
- (instancetype)initWithUserName:(NSString *)userName age:(NSUInteger)age;
+ (instancetype)userWithUserName:(NSString *)userName age:(NSUInteger)age;
@end
model类.m文件:
#import "LQUserModel.h"
@implementation LQUserModel
- (instancetype)initWithUserName:(NSString *)userName age:(NSUInteger)age{
if (self = [super init]) {
_userName = [userName copy];
_age = age;
}
return self;
}
+ (instancetype)userWithUserName:(NSString *)userName age:(NSUInteger)age{
return [[LQUserModel alloc]initWithUserName:userName age:age];
}
@end
定义了一个有LQUserModel
对象的控制器CopyingTestViewController
:
#import <UIKit/UIKit.h>
@class LQUserModel;
@interface CopyingTestViewController : UIViewController
@property (nonatomic, copy) LQUserModel *userModel;
@end
现在我们来进行一个页面切换,我将代码写在了touch方法里:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CopyingTestViewController *copyingVC = [[CopyingTestViewController alloc]init];
LQUserModel *model = [[LQUserModel alloc]initWithUserName:@"John" age:18];
// LQUserModel *model = [LQUserModel userWithUserName:@"John" age:18];
copyingVC.userModel = model;
[self presentViewController:copyingVC animated:YES completion:nil];
}
运行程序,当进行切换操作时,crash了...
2018-01-17 14:22:02.697557+0800 RLAudioRecord[10091:2180904] -[LQUserModel copyWithZone:]: unrecognized selector sent to instance 0x10089297
LQUserModel
对象没有实现方法copyWithZone:
,而copyWithZone:
是协议NSCopying
的方法,所以我们需要遵守该协议
@interface LQUserModel : NSObject<NSCopying>
- (id)copyWithZone:(nullable NSZone *)zone{
LQUserModel *model = [[LQUserModel allocWithZone:zone]init];
[LQUserModel userWithUserName:_userName age:_age];
return model;
}
ok,问题得到修复,我们来讲下NSCopying
这个协议方法的什么时候使用的,我们在定义LQUserModel
对象时,指定其属性为copy
:
@property (nonatomic, copy) LQUserModel *userModel;
如果自定义类需要有copy
属性,该类需要遵守协议<NSCopying>
,并实现其协议方法copyWithZone:
。
系统中<NSCopying>
和<NSMutableCopying>
协议方法:
@protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(nullable NSZone *)zone;
@end
使用对象实例可变时,使用协议NSMutableCopying
,不可变时使用NSCopying
。