Chr*_*son 6 design-patterns objective-c
我正在使用NSProgress在我的iOS应用程序中传达文件下载的进度.这是一个非常通用的类,我有点害怕它的固有能力,尤其是两个完成处理属性.有一个用于处理取消,一个用于暂停(但没有一个用于完成,这可能是一个打击......)
这些处理程序的目的是什么?执行下载的代码可以在其中放置逻辑来处理用户发起的取消和暂停.但是,没有什么能阻止客户端用UI代码覆盖处理程序.
那么,它是否适用于UI?我不确定这是一个有用的模式,因为UI无论如何都会产生取消或暂停.此外,如果您使用progress对象同时显示多个UI元素的进度(在MacOS中使用它的方式),则不同的UI元素可能都需要自己的完成处理程序.
使用处理程序将用户操作传递回下载控制器似乎是最有用的模式,但是我希望在初始化时设置处理程序,然后保持只读.
我在这里错过了什么?
(PS现在我根本不会使用那些处理程序并依赖KVO.但是,我有一种痒的感觉,我错过了课程背后的一些基本想法)
我相信您缺少的关键是该类NSProgress被设计为用作进度对象树。此外,这棵树是用子进度对象隐式创建的,不需要知道它们附加到父级,这就是它真正的力量所在。
我发现 OS X Foundation 发行说明比类参考更有帮助NSProgress:
https://developer.apple.com/library/Mac/releasenotes/Foundation/RN-Foundation/index.html
处理程序似乎可用于 UI 控制器逻辑和数据控制器逻辑的原因是,当您构建父子层次结构时,您有两组可用于两者的处理程序。父级的处理程序将在 UI 控制器级别(进度的“消费者”)设置,而子级的处理程序将由数据控制器(“提供者”)设置。
由于可以使用子进度对象隐式创建关系,因此becomeCurrentWithPendingUnitCount:子进度对象将与父进度对象隔离,这将减轻您对客户端用自己的处理程序覆盖任何数据级处理程序的担忧。
在进度对象上调用pause或cancel将会在树中传播该调用,并调用途中的任何处理程序。
一个例子:
// UI controller level, probably a UIViewController subclass.
- (void)handleDoSomethingButtonTapped:(UIButton *)sender
{
self.progressThatWeObserve =
[NSProgress progressWithTotalUnitCount:100]; // 100 is arbitrary
self.progressThatWeObserve.pausingHandler = ^{
// Update UI, reflect paused state ...
};
[self.progressThatWeObserve becomeCurrentWithPendingUnitCount:100];
[self.dataController doSomethingInBackgroundWithCompletionHandler:^{
// Update UI, remove from view ...
}];
[self.progressThatWeObserve resignCurrent];
}
// Data controller level, a SomethingManager class maybe.
- (void)doSomethingInBackgroundWithCompletionHandler:(void (^)(void)completionHandler
{
self.progressThatWeManipulate =
[NSProgress progressWithTotalUnitCount:289234]; // e.g. bytes to upload
self.progressThatWeManipulate.pausingHandler = ^{
// Actually suspend the network operation ...
};
dispath_async(self.workerQueue, ^{
// Periodically update progress
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,我实际上没有做过任何这些,这都是阅读文档中的理论。
| 归档时间: |
|
| 查看次数: |
1472 次 |
| 最近记录: |