objective-c - Objective-C 中的以下代码有什么问题?
问题描述
我有一个面试,我有这个问题,但我失败了。有人可以指出这里有什么问题吗?
因此,在公司,我看到了这段代码,并要求我用下面的代码找出尽可能多的问题:
文件 T1.h
#import <Foundation/Foundation.h>
typedef void (^TestClassCallback)();
// Person is a subclass of NSManagedObject
@class Person;
@interface T1 : NSObject
- (void)doWorkWithPerson:(Person*)aPerson callback:(TestClassCallback)aCallback;
@end
文件 T1.m
#import "T1.h"
#import "Person.h"
#import "ProgressBar.h"
@implementation T1
static TestClassCallback savedCallback;
- (void)doWorkWithPerson:(Person*)aPerson callback:(TestClassCallback)aCallback {
savedCallback = aCallback;
[self performSelectorInBackground:@selector(doVeryLongTask1:) withObject:aPerson];
}
- (void)doVeryLongTask1:(Person*)aPerson {
double p = 0.0;
// Do some actions.
// ...
// ...
[[ProgressBar instance] update:p];
// Do more actions.
// ...
// ...
[[ProgressBar instance] update:p];
// Do final actions.
(savedCallback)();
}
@end
据我所知,回调和发送到后台的问题,以及更新进度条。
解决方案
我看到的主要问题是,如果在原始调用完成之前再次调用它,您将覆盖savedCallback
并且永远不会调用原始调用的回调(并且第二个将被调用两次)。
在 2018 年,我将放弃相当陈旧的基于选择器的方法在后台运行任务,转而使用基于块的 GCD。所以,像这样:
- (void)doWorkWithPerson:(Person*)aPerson callback:(TestClassCallback)aCallback {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
[self doVeryLongTask1:aPerson];
aCallback();
});
}
推荐阅读
- google-chrome - 来自不同来源 Chrome 扩展程序的 IndexedDB 访问
- django - 用 " " 反转没有参数 Not Found。Django (NoReverseMatchError
- json - 使用 NiFi 中的常量将嵌套 JSON 转换为 CSV
- python - 格式化列表以包含逗号和空格
- matlab - 二进制 (0-1) 矩阵的双字典排序
- python-3.x - 使用回归线在 Altair 中可视化多个列的快速方法
- python - tkinter 停止打开多个窗口
- java - azure-documentdb:需要帮助:客户端创建失败并出现 Json 异常
- kubernetes - 在 Kubernetes 中,如何等待一个 pod 完成删除后再开始新的
- html - 选择角度材料模态中的第二个按钮