我接受了采访,并且有这个问题,但是我失败了。有人可以指出这里有什么问题吗?
因此,在公司中,我被告知此代码,并被要求使用以下代码找出尽可能多的问题:
文件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
据我所知,回调和发送到后台以及更新进度栏的问题。
答案 0 :(得分:1)
我看到的主要问题是,如果在原始调用完成之前再次调用它,您将覆盖savedCallback
,并且原始调用的回调将永远不会被调用(第二个回调将被调用两次)。
在2018年,我放弃了基于陈旧的基于选择器的方法来在后台运行任务,而改为使用基于块的GCD。所以,像这样:
- (void)doWorkWithPerson:(Person*)aPerson callback:(TestClassCallback)aCallback {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
[self doVeryLongTask1:aPerson];
aCallback();
});
}