2016-08-09 15 views
1

私は迅速なアプリを持っています。メインクラスviewdidloadはobjective-c関数を呼び出します。Swiftで続行する前に、目的のC関数の結果を待つ

objective-c関数はデータベースをスキャンし、それをNSMutableArrayに格納します。

swift関数でNSMutable配列を使用する必要があります。

問題はこれです:私はswiftでobjective-c関数を呼び出してから配列を使用しますが、配列が塗りつぶされる前に使用されます(nil)。

したがって、配列を呼び出す前にobjective-c関数からの戻り値が正常に返されるまで待つ必要があります。

私は複数の例を見てきましたが、ある言語から別のものには見られませんでした。一部の人々は使用完了ハンドラを言っている他の人は、最高の方法ではないと言う。その後、他の人は通知を出しました。

私はIOSに新しいですので、あなたの助けに感謝します。

EDITED追加したコード

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  
} 
+0

コードを表示できますか? – AdamPro13

+0

OCとSwiftを扱うのは面倒です。あなたの質問はあまりにも一般的です。 – Lumialxk

+0

意見を聞かないでください。あなたが実装して働くことができるものを見つけてください。プログラミングの経験が増えるにつれて、関わる問題をより深く理解し、なぜ1つのアプローチが他のアプローチより優れているのかを理解する必要があります。 – Avi

答えて

1

問題は、これが非同期であるということです関数にアクセスし、結果に同期的にアクセスしようとしています。あなたはそれが終わっていますとき、あなたがそれにアクセスできるようにブロックを使用するためにObjective 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; 
+0

ありがとうございました!私はエラーが戻ってきていないので、私はリターンnilをもう一度追加し、それを修正しました(それは欠落していたのでしょうか?)。迅速な側にも。この関数を呼び出して配列を使用すると、if文でこれを行いますか?あなたの助けをもう一度ありがとう。 –

+0

私は 'return nil'を削除しましたが、エラーであった' continueWithBlock:^ id'を見た後、戻り値が必要です。これを即座に呼び出すと完了ハンドラが使用され、そうであれば、配列を通常の配列として使用し、ifステートメントを使用して、必要に応じてカウントが0より大きいかどうかを確認できます。オートコンプリートは即座に機能コールを書くときにクロージャを追加する必要があります。 – Swinny89

+0

修正されたコード「コントロールは非空白ブロックの終わりに達します」と同じエラーが発生します。 –

関連する問題