ios - 在 Swift 中继续之前等待 Objective-C 函数的结果

标签 ios objective-c event-handling

我有一个 swift 应用程序。主类 viewdidload 调用一个 objective-c 函数。

objective-c 函数扫描数据库,然后将其放入 NSMutableArray。

我需要在 swift 函数中使用 NSMutable 数组。

问题是这样的:我在 swift 中调用了 objective-c 函数,然后使用数组,但它在数组被填充之前就使用了它(nil)。

所以我需要 swift 在读取数组之前等待 objective-c 函数的成功返回值。

我见过多个例子,但不是从一种语言到另一种语言。有些人说使用完成处理程序其他人说这不是最好的方法。然后其他人说通知。

我是 IOS 新手,非常感谢您的帮助。

编辑添加的代码

scanTable 函数( Objective-C ):

#import "ScanTable.h"
#import "Mapper.h"

@implementation ScanTable

- (void) scanTableDo {
    AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
    AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
    scanExpression.limit = @10;

    [[dynamoDBObjectMapper scan:[Mapper class] 
                     expression:scanExpression]
              continueWithBlock:
        ^id(AWSTask *task) {
            if (task.error) {
                NSLog(@"The request failed. Error: [%@]", task.error);
            }
            if (task.exception) {
                NSLog(@"The request failed. Exception: [%@]", task.exception);
            }
            if (task.result) {
                AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
                NSMutableArray *scanResult = [[NSMutableArray alloc] initWithArray:paginatedOutput.items];  //// ADDED /////
            }
            return nil;
    }];     
}
@end

主要功能(Swift):

override func viewDidLoad() {
    super.viewDidLoad()

    let scanTable = ScanTable();       
    scanTable.scanTableDo();

    let swiftArray = scanTable.scanResult     
}

最佳答案

问题在于这是一个异步函数,而您正试图以同步方式访问结果。您需要 objective-c 函数来使用一个 block ,以便您可以在它完成时访问它:

- (void)scanTableDoWithBlock:(void(^)(NSArray *scanResult, NSError *error))handler {

    AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
    AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
    scanExpression.limit = @10;


    [[dynamoDBObjectMapper scan:[Mapper class]
                     expression:scanExpression]
     continueWithBlock:^id(AWSTask *task) {
         if (task.error) {
             NSLog(@"The request failed. Error: [%@]", task.error);
             if (handler != nil) {
                 handler(nil, task.error);
             }
         }
         if (task.exception) {
             NSLog(@"The request failed. Exception: [%@]", task.exception);
         }
         if (task.result) {
             AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
             NSMutableArray *scanResult = [[NSMutableArray alloc] initWithArray:paginatedOutput.items];  //// ADDED /////

             if (handler != nil) {
                 handler([scanResult copy], nil);
             }
         } 

         return nil;
     }];    
}

确保将 .h 文件中的方法声明更改为:

- (void)scanTableDo;

到:

- (void)scanTableDoWithBlock:(void(^)(NSArray *scanResult, NSError *error))handler;

关于ios - 在 Swift 中继续之前等待 Objective-C 函数的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38844211/

相关文章:

ios - 如何在我的 Swift 类中使用 Objective-c 方法

ios - UINavigationBar - 改变高度/添加大按钮

javascript - Puppeteer:有什么方法可以获取 page.on() 的所有事件监听器吗?

javascript - 在循环中附加事件

c# - 事件处理程序会阻止垃圾收集的发生吗?

ios - 为什么特定站点在 React Native Webview 中显示为 "Error"?

objective-c - reloadData 崩溃的 iOS 应用程序

ios - Cocoa Touch 获取用户全名

iOS Today Extension 在 iPhone 上不断崩溃,而不是在模拟器中

ios - 如何识别iOS中的单个单击和双击 View ?