异步添加数组中的数据

时间:2016-08-30 12:24:37

标签: ios grand-central-dispatch semaphore nsoperationqueue

我有8个单独的函数,它们都返回了我需要将数据存储在数组中的数据。将数据存储到数组中并通知该数组已存储所有数据的最佳方法是什么。这样我就可以在另一个视图控制器中传递它。例如,我有f1(),f2()...并且都返回一个字符串,我想将它存储在dataArray中。如果所有功能都在那里完成,我必须将这些数据传递给另一个vc。

3 个答案:

答案 0 :(得分:2)

您需要的工具是一个调度组和一个串行调度队列来收集结果。序列化更新结果非常重要,因为修改数组不是线程安全的。当然,您可以将所有这些都包含在通用解决方案中。作为一个没有经过严格测试的快速示例(并且稍微有些奇怪,因为它是自我保留的,所以可能令人困惑),但演示了基本方法:

class Dispatcher<Element> {
    let resultsQueue = DispatchQueue(label: "dispatcher") // Default is serial
    var results: [Element] = []
    init(functions: [() -> Element], completion: @escaping ([Element]) -> Void) {

        let group = DispatchGroup()
        let queue = DispatchQueue.global()
        for f in functions {
            queue.async(group: group) {
                let result = f()
                self.resultsQueue.sync { self.results.append(result) }
            }
        }

        // Just picking main here as a random place to perform the update.
        // You could also pass it in.
        group.notify(queue: DispatchQueue.main) { completion(self.results) }
    }
}

Dispatcher(functions: [{ return 1 }, { return 2 }], completion: { print($0) })
  

我必须将此数据传递给另一个vc

请注意,这强烈暗示您做错了。视图控制器不应该计算数据,绝对不应该异步将数据传递给其他视图控制器。视图控制器负责显示数据,并且可以在屏幕外的任何时候自由销毁(第二个视图控制器可能不在屏幕上,甚至在完成块运行时也存在)。应将工作移至模型类,视图控制器应观察模型并自行更新,然后模型完成其工作。但是这个Dispatcher类仍然可以对此有所帮助。

答案 1 :(得分:0)

通知必须使用NSNotificationCenter

在视图控制器viewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

      [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(receiveNotification:)
                                             name:@"DataReceivedNotification"
                                           object:nil];
}

- (void)receiveNotification:(NSNotification *)notification
{
    NSArray *receivedData = notification.object;

    NSLog(@"%@",receivedData);
}

在函数类

- (void)f1
{
    //Store the received data in array
    NSArray *data = [NSArray arrayWithObjects:(nonnull id), ..., nil];

    //Post notification
    [[NSNotificationCenter defaultCenter] postNotificationName:@"DataReceivedNotification" object:data];
}

答案 2 :(得分:0)