【问题标题】:Wait for result from objective C function before continuing in Swift在继续使用 Swift 之前等待目标 C 函数的结果
【发布时间】:2016-08-09 07:05:18
【问题描述】:

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

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

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

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

所以我需要 swift 等待 Objective-c 函数成功返回值,然后再唱数组。

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

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

编辑添加代码

scanTable 函数(目标 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     
}

【问题讨论】:

  • 你能展示你的代码吗?
  • 处理OC和Swift很麻烦。而且你的问题太笼统了。
  • 不要听取意见。找到一些你可以实施并开始工作的东西。随着您获得更多编程经验,您应该对所涉及的问题以及为什么一种方法优于另一种方法有更深入的了解。
  • 嗨 @AdamPro13 和 Lumialxk 感谢您的回复。我已经添加了代码。希望这会有所帮助。
  • @Avi 根据我的问题,我找不到适用的方法。否则我会的。不过还是谢谢。

标签: ios objective-c event-handling


【解决方案1】:

问题在于这是一个异步函数,而您正试图以同步方式访问结果。你需要目标 c 函数来使用一个块,这样你就可以在它完成时访问它:

- (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;

【讨论】:

  • 谢谢!我收到一个错误,因为没有返回,我再次添加了 return nil 并修复了它(它是否意味着丢失?)。也在迅速的一边。如果我调用此函数然后使用数组,我会使用 if 语句来执行此操作吗?再次感谢您的帮助。
  • 我删除了return nil,但在查看了错误的continueWithBlock:^id 之后,它确实需要返回。当您在 swift 中调用它时,您将使用完成处理程序,然后是的,您可以将数组用作普通数组,如果需要,使用 if 语句检查计数是否高于 0。自动完成是 swift 应该在你编写函数调用时为你添加闭包。
  • 修改后的代码“控制到达非空块的末尾”时出现相同的错误。
  • continueWithBlock 内唯一的非 void 块,如果你在那里返回 nil,那么我不明白为什么编译器会告诉你,除非你在代码的其他地方有问题. return nil 是块中的最后一行,而不是在 if 语句中?如上图。
  • 感谢我在粘贴时出错。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-29
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多