Receptionist Pattern

Receptionist Pattern
The Receptionist Design Pattern in Practice

    KVO notification会立马调用 observer 的observeValueForKeyPath:ofObject:change:context:方法,如果 observer 在子线程中实现该方法,那么,该方法同样返回在相同的线程.

    在这个模式中,核心对象,即receptionist,扮演着线程中介的角色,正如图片11-1所示
11-1,  
    在这个例子中receptionist即 model 对象的属性观察者,receptionist实现了observeValueForKeyPath:ofObject:change:context:方法,用来将子线程接收到的事件,传递到主线程中执行. 每当model 对象属性发生变化时,receptionist收到 KVO 通知,立马向主线程中添加一个 block,这个 block 中包含着更新用户界面的执行代码.

    为了实现这一模式,首先,你需要定义一个receptionist类,包含一个属性的观察者,然后需要一个把这个 KVO 通知转换成一个界面更新任务的方法, 这个函数需要知道它所观察的对象,具体发生变化的属性,相应的界面变化,和在哪个队列中执行代码. 如下面示例所示:

@interface RCReceptionist : NSObject {
    id observedObject;
    NSString *observedKeyPath;
    RCTaskBlock task;
    NSOperationQueue *queue;
}

其中,这个 block 中需要这样定义:

typedef void (^RCTaskBlock)(NSString *keyPath, id object, NSDictionary *change);

这些参数类似于observeValueForKeyPath:ofObject:change:context:函数,接下来这个类还需要声明一个工厂方法,包含 block 作为参数:

+ (id)receptionistForKeyPath:(NSString *)path
        object:(id)obj
         queue:(NSOperationQueue *)queue
          task:(RCTaskBlock)task;

具体实现:

+ (id)receptionistForKeyPath:(NSString *)path object:(id)obj queue:(NSOperationQueue *)queue task:(RCTaskBlock)task {
    RCReceptionist *receptionist = [RCReceptionist new];
    receptionist->task = [task copy];
    receptionist->observedKeyPath = [path copy];
    receptionist->observedObject = [obj retain];
    receptionist->queue = [queue retain];
    [obj addObserver:receptionist forKeyPath:path
             options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:0];
    return [receptionist autorelease];
}

此处,需要对 block 进行 copy, 因为 block 很有可能是在栈中创建的,必须拷贝到堆中,这样在 KVO 通知分发出去的时候才能继续保持在内存中.

接下来,类还需要实现observeValueForKeyPath:ofObject:change:context:方法,

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
        change:(NSDictionary *)change context:(void *)context {
    [queue addOperationWithBlock:^{
        task(keyPath, object, change);
    }];
}

这段代码只是简单的将刷新任务放入到接收的指定队列中,并且将观察对象的属性变化放入 block 中传递出去,此处 task 被将封装成NSBlockOperation对象用来在队列中执行任务.

需要更新界面的对象在创建receptionist对象时,提供具体的界面更新代码,注意,当创建receptionist对象时,需要传递具体 block 需要执行在哪个queue中,在这段示例代码中,是主线程.

RCReceptionist *receptionist = [RCReceptionist receptionistForKeyPath:@"value" object:model queue:mainQueue task:^(NSString *keyPath, id object, NSDictionary *change) {
            NSView *viewForModel = [modelToViewMap objectForKey:model];
            NSColor *newColor = [change objectForKey:NSKeyValueChangeNewKey];
            [[[viewForModel subviews] objectAtIndex:0] setFillColor:newColor];
        }];
 
内容概要:本文针对国内加密货币市场预测研究较少的现状,采用BP神经网络构建了CCi30指数预测模型。研究选取2018年3月1日至2019年3月26日共391天的数据作为样本,通过“试凑法”确定最优隐结点数目,建立三层BP神经网络模型对CCi30指数收盘价进行预测。论文详细介绍了数据预处理、模型构建、训练及评估过程,包括数据归一化、特征工程、模型架构设计(如输入层、隐藏层、输出层)、模型编译与训练、模型评估(如RMSE、MAE计算)以及结果可视化。研究表明,该模型在短期内能较准确地预测指数变化趋势。此外,文章还讨论了隐层节点数的优化方法及其对预测性能的影响,并提出了若干改进建议,如引入更多技术指标、优化模型架构、尝试其他时序模型等。 适合人群:对加密货币市场预测感兴趣的研究人员、投资者及具备一定编程基础的数据分析师。 使用场景及目标:①为加密货币市场投资者提供一种新的预测工具和方法;②帮助研究人员理解BP神经网络在时间序列预测中的应用;③为后续研究提供改进方向,如数据增强、模型优化、特征工程等。 其他说明:尽管该模型在短期内表现出良好的预测性能,但仍存在一定局限性,如样本量较小、未考虑外部因素影响等。因此,在实际应用中需谨慎对待模型预测结果,并结合其他分析工具共同决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值