编程思想:
面向过程:处理事情以过程为核心,一步一步的实现。给第一次软件危机埋下了伏笔。
面向对象:万物皆对象(没有对象New一个)。
链式编程思想:将多个操作(所行代码)通过点号(.)链接在一起成为一句代码,目的是可读性好。链式编程最大的特点:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)。
示例代码:
CalculateManager
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface CalculateManager : NSObject
@property (nonatomic, assign) int result;
- (CalculateManager *(^)(int))add;
@end
NS_ASSUME_NONNULL_END
#import "CalculateManager.h"
@implementation CalculateManager
- (CalculateManager *(^)(int))add{
__weak typeof(self) weakSelf = self;
return ^(int value){
weakSelf.result += value;
return self;
};
}
@end
#import "NSObject+Calculate.h"
#import <Foundation/Foundation.h>
#import "CalculateManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (Calculate)
+ (int)mcf_makeCaculate:(void(^)(CalculateManager *))block;
@end
NS_ASSUME_NONNULL_END
#import "NSObject+Calculate.h"
@implementation NSObject (Calculate)
+ (int)mcf_makeCaculate:(void(^)(CalculateManager *))block{
CalculateManager *cgmr = [[CalculateManager alloc] init];
block(cgmr);
return cgmr.result;
}
@end
ViewController
#import "ViewController.h"
#import "NSObject+Calculate.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
int result = [NSObject mcf_makeCaculate:^(CalculateManager * make) {
make.add(20).add(40).add(2);
}];
NSLog(@"result==%d",result);
}
@end
2022-02-02 20:56:33.479389+0800 链式编程学习[4974:349410] result==62
响应式编程思想
:不需要考虑调用顺序,只需要知道考虑结果,类似于蝴蝶效应,产生一个事件,会影响很多东西,这些事件像流一样的传播出去,然后影响结果,借用面向对象的一句话,万物皆是流。
KVO
示例代码:
#import "Person.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
{
@public
NSString *_name;
}
@property (nonatomic, strong) NSString *name;
@end
NS_ASSUME_NONNULL_END
#import "Person.h"
@implementation Person
- (void)setName:(NSString *)name{
_name = [NSString stringWithFormat:@"%@bbbb",name];
}
@end
#import "NSObject+KVO.h"
#import "NSObject+KVO.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (KVO)
// KVO怎么实现
// KVO的本质就是监听一个对象有没有调用set方法
// 重写这个方法
// 监听方法本质:并不需要修改方法的实现,仅仅想判断下有没有调用
- (void)mcf_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
@end
NS_ASSUME_NONNULL_END
#import <objc/message.h>
#import "MCFKVONotifying_Person.h"
NSString *const observerKey = @"observer";
@implementation NSObject (KVO)
- (void)mcf_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{
/*
// 1.自定义NSKVONotifying_Person子类
// 2.重写setName,在内部恢复父类做法,通知观察者
// 3.如何让外界调用自定义Person类的子类方法,修改当前对象的isa指针,指向NSKVONotifying_Person
*/
//把观察者保存到当前对象中
objc_setAssociatedObject(self, (__bridge const void * _Nonnull)(observerKey), observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//修改对象isa指针
object_setClass(self, [MCFKVONotifying_Person class]);
}
MCFKVONotifying_Person
#import "Person.h"
NS_ASSUME_NONNULL_BEGIN
@interface MCFKVONotifying_Person : Person
@end
NS_ASSUME_NONNULL_END
#import "MCFKVONotifying_Person.h"
#import <objc/message.h>
extern NSString* const observerKey;
@implementation MCFKVONotifying_Person
- (void)setName:(NSString *)name{
[super setName: name];
//通知观察者调用observeValueForKeyPath
//需要把观察者包保存到当前对象
//获取观察者
id observer = objc_getAssociatedObject(self, observerKey);
[observer observeValueForKeyPath:@"name" ofObject:self change:nil context:nil];
}
@end
ViewController
#import "ViewController.h"
#import "Person.h"
#import "NSObject+KVO.h"
@interface ViewController ()
@property (nonatomic, strong) Person *p;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
Person *p = [[Person alloc] init];
[p mcf_addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
_p = p;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
NSLog(@"%@",_p.name);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
static int i = 0;
i++;
_p.name = [NSString stringWithFormat:@"%d",i];
}
@end
2022-02-02 21:50:04.374226+0800 响应式编程[6060:398126] 1bbbb
2022-02-02 21:50:04.839348+0800 响应式编程[6060:398126] 2bbbb
函数式编程:把操作尽量写成一系列嵌套的函数或者方法调用。
本质:就是往方法里传入Block,方法中嵌套block调用,把代码聚合起来管理
特点:每个方法必须有返回值,把函数或者block当作参数,block参数(需要操作的值)block返回的值(操作结果)。
示例代码
CalculateManager
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface CalculateManager : NSObject
@property (nonatomic, assign) int result;
- (instancetype)caculate:(int(^)(int))caculateBlock;
@end
NS_ASSUME_NONNULL_END
#import "CalculateManager.h"
@implementation CalculateManager
- (instancetype)caculate:(int (^)(int))caculateBlock{
_result = caculateBlock(_result);
return self;
}
@end
ViewController
#import "ViewController.h"
#import "CalculateManager.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CalculateManager *mgr = [[CalculateManager alloc] init];
int result = [[mgr caculate:^int(int result) {
result += 4;
result += 4;
return result;
}] result];
NSLog(@"result====%ld",result);
}
@end
2022-02-02 22:01:28.831263+0800 函数式编程[6283:411450] result====8
ReactiveCocoa 融合了函数式编程以及响应式编程的框架,RAC解决问题直接考虑结果,把每次操作都写成一系列嵌套的方法,式代码高聚合,方便管理。