Objective-C中的协议

2018-01-22 10:48:25来源:https://www.jianshu.com/p/7db43a37d666作者:恩来客人点击

分享

先给出一个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





微信扫一扫

第七城市微信公众平台