首页 > 解决方案 > 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 

据我所知,回调和发送到后台的问题,以及更新进度条。

标签: objective-c

解决方案


我看到的主要问题是,如果在原始调用完成之前再次调用它,您将覆盖savedCallback并且永远不会调用原始调用的回调(并且第二个将被调用两次)。

在 2018 年,我将放弃相当陈旧的基于选择器的方法在后台运行任务,转而使用基于块的 GCD。所以,像这样:

- (void)doWorkWithPerson:(Person*)aPerson callback:(TestClassCallback)aCallback {
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
        [self doVeryLongTask1:aPerson];
        aCallback();
    });
}

推荐阅读