链式编程思想和响应式编程思想初窥

2017-04-21  本文已影响32人  952625a28d0d

方法返回值必须有方法调用者

Masonry

链式编程

#import <Foundation/Foundation.h>
#import "sumManager.h"


@interface NSObject (sum)

/**
 *  给NSObject添加一个类方法
 *
 *  @param block Block参数为sumManager
 *
 *  @return 结果
 */
+ (int)jyf_makeContraons:(void(^)(sumManager *mgr))block;

@end
#import "NSObject+sum.h"

@implementation NSObject (sum)

+ (int)jyf_makeContraons:(void (^)(sumManager *))block{
    
    // 首先初始化一个sumManager
    sumManager *mgr = [[sumManager alloc] init];
    
    // Block返回mgr对象
    block(mgr);
    
    // 返回结果
    return mgr.result;
}
#import <Foundation/Foundation.h>

@interface sumManager : NSObject

/**
 *  结果
 */
@property (nonatomic, assign) int result;

//- (instancetype)add:(int)value;
/**
 *  返回结果管理者Self
 */
- (sumManager *(^)(int))add;

@end
#import "sumManager.h"

@implementation sumManager

/**
 *  实现add方法 加值之后返回Self
 */
- (sumManager *(^)(int value))add{
    
    return ^(int value){
        _result += value;
        return self;
    };
}

@end

响应式编程

#import "ViewController.h"
#import "Person.h"

@interface ViewController ()

@property (nonatomic, strong) Person *p;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    Person *p = [[Person alloc] init];
    
    // 监听name属性
    [p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    _p = p;
}

// 一旦 p对象的name属性变化 哥们就来了
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSLog(@"%@",self.p.name);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    static int i = 0;
    i++;
    _p.name = [NSString stringWithFormat:@"%d",i];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

自定义KVP的实现过程以及思想

#import <Foundation/Foundation.h>

@interface NSObject (JYFKVO)

- (void)jyf_addObserver:(nonnull NSObject *)observer forKeyPath:(nonnull NSString *)keyPath options:(NSKeyValueObservingOptions)option context:(nullable void *)context;


@end
#import "NSObject+JYFKVO.h"

// 因为要通知外界 所以必然要发送消息
#import <objc/message.h>

@implementation NSObject (JYFKVO)

/**
 *  监听对象的某一个属性
 *
 *  @param observer 监听者
 *  @param keyPath  keyPath
 *  @param context  context
 */

// self ==> 被观察者(Person)
// observer ==> 观察者
- (void)jyf_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)option context :(void *)context{
    /**
     1:自定义子类对象
     2:重写被监听的对象的setName,在方法中我们来调用super的,调用完毕,通知观察者
     3:修改当前对象的isa指针,让它指向我们自定义的子类!!
     */
    
    // 1:动态生成一个类
    // 1.1:创建Self的子类!第一步:获取类名
    NSString *oldClassName = NSStringFromClass([self class]);
    
    // 新的类名
    NSString *newClassName = [@"jyfKVO_" stringByAppendingString:oldClassName];
    
    // 转成C字符串
    const char * newName = [newClassName UTF8String];
    
    // 创建一个类的Class对象
    Class MyClass = objc_allocateClassPair([self class], newName, 0);
    
    // 注册类 到我们的项目中
    objc_registerClassPair(MyClass);
    
    // 2:重写Set方法 添加set方法
    // v@:@ 表示没有返回值 没有参数
    class_addMethod(MyClass, @selector(setName:), (IMP)setName, "v@:@");
    
    // 3: 修改isa指针 把self的指针 改成我们自定义的子类
    object_setClass(self, MyClass);
    
    // 4:保存观察者对象
    objc_setAssociatedObject(self, @"objc", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

// 1:调用super的set方法
// 2:通知我们的外界
void setName(id self, SEL _cmd, NSString * newName){
    
    // 复写 调用super的setname方法
    
    // 保存子类类型
    id class = [self class];
    
    // 改变self的isa指针
    object_setClass(self, class_getSuperclass(class));
    
    // 调用父类的set方法
    objc_msgSend(self, @selector(setName:),newName);
    
    // 拿到观察者
    id objc = objc_getAssociatedObject(self, @"objc");
    
    // 通知观察者
    objc_msgSend(objc, @selector(observeValueForKeyPath:ofObject:change:context:),self,@"name",nil,nil);
    
    // 改回子类类型
    object_setClass(self, class);
}

@end
Paste_Image.png
上一篇 下一篇

猜你喜欢

热点阅读