iOS 协议
2020-12-22 本文已影响0人
青椒辣不辣
iOS 数据存储(NSCopying)
NSSecureCoding:在NSCoding基础上增加了安全性
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
RJUserBaseInfo *userInfo1 = [[RJUserBaseInfo alloc]init];
userInfo1.mutableName = @"mutableName".mutableCopy;
userInfo1.name = @"name";
userInfo1.age = 10;
RJUserBaseInfo *userInfo2 = userInfo1.copy;
RJUserBaseInfo *userInfo3 = userInfo1.mutableCopy;
[userInfo1.mutableName appendString:@"1"];
[userInfo2.mutableName appendString:@"2"];
[userInfo3.mutableName appendString:@"3"];
userInfo2.age = 20;
userInfo3.age = 30;
NSLog(@"---userInfo1---%@",userInfo1);
NSLog(@"---mutableName1 = %@-%p",userInfo1.mutableName,userInfo1.mutableName);
NSLog(@"---name1 = %@-%p\n---age1 = %d",userInfo1.name,userInfo1.name,userInfo1.age);
NSLog(@"---userInfo2---%@",userInfo2);
NSLog(@"---mutableName2 = %@-%p",userInfo2.mutableName,userInfo2.mutableName);
NSLog(@"---name2 = %@-%p\n---age2 = %d",userInfo2.name,userInfo2.name,userInfo2.age);
NSLog(@"---userInfo3---%@",userInfo3);
NSLog(@"---mutableName3 = %@-%p",userInfo3.mutableName,userInfo3.mutableName);
NSLog(@"---name3 = %@-%p\n---age3 = %d",userInfo3.name,userInfo3.name,userInfo3.age);
}
---userInfo1---<RJUserBaseInfo: 0x600002676040>
---mutableName1 = mutableName12-0x600002801140
---name1 = name-0x10d39f6c8
---age1 = 10
---userInfo2---<RJUserBaseInfo: 0x600002676080>
---mutableName2 = mutableName12-0x600002801140
---name2 = name-0x10d39f6c8
---age2 = 20
---userInfo3---<RJUserBaseInfo: 0x6000026760a0>
---mutableName3 = mutableName3-0x600002800ff0
---name3 = name-0x10d39f6c8
---age3 = 30
------------------------------------------------------------------------
@interface RJUserBaseInfo : NSObject<NSCopying,NSMutableCopying>
@property (nonatomic, strong) NSMutableString *mutableName;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
@end
------------------------------------------------------------------------
@implementation RJUserBaseInfo
-(id)copyWithZone:(NSZone *)zone{
RJUserBaseInfo *userInfo = [[self class] allocWithZone:zone];
userInfo.mutableName = self.mutableName;//这里是浅复制
userInfo.name = self.name;
userInfo.age = self.age;
return userInfo;
}
-(id)mutableCopyWithZone:(NSZone *)zone{
RJUserBaseInfo *userInfo = [[self class] allocWithZone:zone];
userInfo.mutableName = [self.mutableName mutableCopy];//这里是深复制
userInfo.name = self.name;
userInfo.age = self.age;
return userInfo;
}
@end
image.png
image.png
使用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//不同的类使用统一入口传递数据(一个协议对应多个类)
RJPerson *person = [[RJPerson alloc]init];
person.delegate = (RJTextTwoViewController <RJPerson>*)self;//此种写法无提示
[person rj_setData:@{@"name":@"曹操",@"adress":@"东汉曹家庄",@"age":@"36"}];
[person rj_eat];
//面向接口编程:将接口(声明)和实现分离,对外只暴露接口(一个协议对应一个类)
id<RJJadeEmperor> jadeEmperor = [RJGodBridge serverForProtocol:@protocol(RJJadeEmperor)];
[jadeEmperor rj_IssuingTheDecreeOfJadeEmperor];
id<RJDragonKing> dragonKing = [RJGodBridge serverForProtocol:@protocol(RJDragonKing)];
[dragonKing rj_DragonKingOfTheEastChinaSeaRainfall];
//控制链式编程的调用顺序
NSString *sql = [RJSQLTool makeSQL:^(RJSQLTool<Selectable> * _Nonnull tool) {
tool.select(@"111").from(@"222").where(@"333"); // 不能改变调用顺序
tool.MyBlock(@"block重写getter");//block重写getter
}];
NSLog(@"%@", sql);
}
-(void)rjperson:(RJPerson *)person goHomeWithSpeed:(NSInteger)speed{
NSLog(@"%@回家速度:%ld迈",person,speed);
}
name=曹操 adress=东汉曹家庄 age=36回家速度:50迈
PersonEat
rj_IssuingTheDecreeOfJadeEmperor
rj_DragonKingOfTheEastChinaSeaRainfall
MyBlock---block重写getter
初始值111222333
RJPerson
@class RJPerson;
NS_ASSUME_NONNULL_BEGIN
/*
1,公开方法一般都放在.h文件中,如果想隐藏实现细节,可以把这些方法放到协议中,再让该类遵守此协议(一个协议对应一个类)
2,将一些公共方法抽取出来封装成协议,任何类想拥有这些方法,只需遵守此协议即可(一个协议对应多个类)
*/
/*
1,协议只有方法的声明,没有方法的实现
2,遵守协议只能在类的声明@interface上,不能在类的实现@implementation上
3,一个协议可以遵守多个其他协议
4,一个协议若遵守了其他协议,就拥有其他协议所有方法的声明
5,一个协议可以被多个类遵守,一个类可以遵守多个协议
6,一个类若遵守了某个协议,就必须实现协议中@required修饰的方法
7,若父类遵守了某个协议,子类也就遵守了此协议
*/
@protocol RJPerson <NSObject>
/*
{
NSString *home;//不能声明成员变量
}
*/
@required//修饰符:表示必须实现
- (void)rj_eat;
@optional//修饰符:表示可选实现
@property (assign ,nonatomic) int age;//使用场景: 声明属性,必须在遵守此协议的类中调用@syntheszie才能正常使用
- (void)rj_setData:(NSDictionary *)data; //使用场景: 不同的类使用统一入口传递数据(一个协议对应多个类)
- (void)rj_run;
- (void)rjperson:(RJPerson *)person goHomeWithSpeed:(NSInteger)speed;
@end
@interface RJPerson : NSObject<RJPerson>
@property (nonatomic,assign)id<RJPerson> delegate;
@property (strong ,nonatomic) NSString *name;
@property (strong ,nonatomic) NSString *adress;
@end
NS_ASSUME_NONNULL_END
---------------------------------------------------------------------------------
@implementation RJPerson
@synthesize age;
- (void)rj_eat {
if ([self.delegate respondsToSelector:@selector(rjperson:goHomeWithSpeed:)]) {
[self.delegate rjperson:self goHomeWithSpeed:50];
}
NSLog(@"PersonEat");
}
-(void)rj_setData:(NSDictionary *)data{
self.name = [data objectForKey:@"name"];
self.adress = [data objectForKey:@"adress"];
self.age = [[data objectForKey:@"age"] intValue];
}
-(NSString *)description{
return [NSString stringWithFormat:@"name=%@ adress=%@ age=%d",self.name,self.adress,self.age];
}
@end
RJGodBridge RJJadeEmperor RJDragonKing
NS_ASSUME_NONNULL_BEGIN
//面向接口编程:将接口(声明)和实现分离,对外只暴露接口(一个协议对应一个类)
@protocol RJJadeEmperor <NSObject>//玉皇大帝
- (void)rj_IssuingTheDecreeOfJadeEmperor;//发布玉帝法旨
@end
@protocol RJDragonKing <NSObject>//龙王
- (void)rj_DragonKingOfTheEastChinaSeaRainfall;//东海龙王 降雨
@end
@interface RJGodBridge : NSObject
+ (void)bindServer:(id)server andProtocol:(Protocol *)protocol;
+ (id)serverForProtocol:(Protocol *)protocol;
@end
NS_ASSUME_NONNULL_END
---------------------------------------------------------------------------------
@interface RJGodBridge ()
@property (nonatomic, strong) NSMutableDictionary<NSString *, id> *serverStore;
@end
@implementation RJGodBridge
- (NSMutableDictionary<NSString *,id> *)serverStore {
if (!_serverStore) {
_serverStore = [NSMutableDictionary new];
}
return _serverStore;
}
+ (instancetype)shared {
static id _bridge = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_bridge = [[self alloc] init];
});
return _bridge;
}
+ (void)bindServer:(id)server andProtocol:(Protocol *)protocol {
if ([server conformsToProtocol:protocol]) {
[[RJGodBridge shared].serverStore setValue:server forKey:NSStringFromProtocol(protocol)];
}
/* [RJGodBridge shared].serverStore
{
RJPerson = "<RJGod: 0x600002c9c060>";
}
*/
}
+ (id)serverForProtocol:(Protocol *)protocol {
return [[RJGodBridge shared].serverStore valueForKey:NSStringFromProtocol(protocol)];
}
@end
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
NS_ASSUME_NONNULL_BEGIN
@interface RJJadeEmperor : NSObject
@end
NS_ASSUME_NONNULL_END
---------------------------------------------------------------------------------
@interface RJJadeEmperor()<RJJadeEmperor>
@end
@implementation RJJadeEmperor
+ (void)load {
[RJGodBridge bindServer:[self new] andProtocol:@protocol(RJJadeEmperor)];
}
-(void)rj_IssuingTheDecreeOfJadeEmperor{
NSLog(@"rj_IssuingTheDecreeOfJadeEmperor");
}
@end
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
NS_ASSUME_NONNULL_BEGIN
@interface RJDragonKing : NSObject
@end
NS_ASSUME_NONNULL_END
---------------------------------------------------------------------------------
@interface RJDragonKing()<RJDragonKing>
@end
@implementation RJDragonKing
+ (void)load {
[RJGodBridge bindServer:[self new] andProtocol:@protocol(RJDragonKing)];
}
-(void)rj_DragonKingOfTheEastChinaSeaRainfall{
NSLog(@"rj_DragonKingOfTheEastChinaSeaRainfall");
}
@end
RJSQLTool
NS_ASSUME_NONNULL_BEGIN
@class RJSQLTool;
@protocol Fromable,Whereable;
typedef RJSQLTool<Fromable>*_Nullable(^Select)(NSString *string);
typedef RJSQLTool<Whereable>*_Nullable(^From)(NSString *string);
typedef RJSQLTool*_Nullable(^Where)(NSString *string);
@protocol Selectable <NSObject>
@property (nonatomic, copy, readonly) RJSQLTool<Fromable>*(^MyBlock)(NSString *string);
@property (nonatomic, copy, readonly) Select select;
@end
@protocol Fromable <NSObject>
@property (nonatomic, copy, readonly) From from;
@end
@protocol Whereable <NSObject>
@property (nonatomic, copy, readonly) Where where;
@end
@interface RJSQLTool : NSObject
+ (NSString *)makeSQL:(void(^)(RJSQLTool<Selectable> *tool))block;
@end
NS_ASSUME_NONNULL_END
---------------------------------------------------------------------------------
@interface RJSQLTool() <Selectable, Fromable, Whereable>
@property (nonatomic, copy) NSString *sql;
@end
@implementation RJSQLTool
- (NSString *)sql {
if (!_sql) {
_sql = @"初始值";
}
return _sql;
}
+ (NSString *)makeSQL:(void(^)(RJSQLTool<Selectable> *tool))block {
if (block) {
RJSQLTool *tool = [RJSQLTool new];
block(tool);
return tool.sql;
}
return nil;
}
-(RJSQLTool<Fromable> * _Nonnull (^)(NSString * _Nonnull))MyBlock{
return ^RJSQLTool<Fromable> * _Nonnull(NSString * _Nonnull string) {
NSLog(@"MyBlock---%@",string);
return self;
};
}
- (Select)select {
return ^RJSQLTool<Fromable> * _Nullable(NSString * _Nonnull string) {
self.sql = [self.sql stringByAppendingString:string];
return self;
};
/*
return ^(NSString *string) {
self.sql = [self.sql stringByAppendingString:string];
return self;
};
*/
}
- (From)from {
return ^(NSString *string) {
self.sql = [self.sql stringByAppendingString:string];
return self;
};
}
- (Where)where {
return ^(NSString *string) {
self.sql = [self.sql stringByAppendingString:string];
return self;
};
}
@end