iOS 协议

2020-12-22  本文已影响0人  青椒辣不辣

\color{rgb(0 ,139, 139)}{<NSCopying>、<NSMutableCopying>、<NSCoding>、<NSSecureCoding>}

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

\color{rgb(0 ,139, 139)}{<NSObject>}


image.png

\color{rgb(0 ,139, 139)}{<自定义@protocol>}
使用

-(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
上一篇下一篇

猜你喜欢

热点阅读