ここで関数を使用して、非同期ブロック(データベースクエリのみ)から値を返します。問題はメモリが原因でアプリケーションがフリーズして終了することです。メインスレッドでこれを実行する方が良いかどうか、それを避けるべきかアドバイスを求めていますか?他のスレッドで実行されていることに注意してください。非同期ブロック戻りの問題
- (NSString *)databaseQuery:(NSString*)ingredient {
__block NSString *valueType = nil;
__block BOOL done = NO;
[[[_ref child:@"ingredients"] queryEqualToValue:valueType childKey:ingredient] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
for (FIRDataSnapshot *child in snapshot.children) {
valueType = child.value;
}
done = YES;
} withCancelBlock:^(NSError * _Nonnull error) {
NSLog(@"%@", error.localizedDescription);
done = YES;
}];
while (!done) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
return valueType;
}
UPDATE 1:以下のコードを使用しようとし、それは同じ結果を生成します。
- (NSString *)databaseQuery:(NSString*)ingredient {
__block NSString *valueType = nil;
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
FIRDatabaseQuery *query = [[_ref child:@"ingredients"] queryEqualToValue:valueType childKey:ingredient] ;
[query observeEventType:FIRDataEventTypeChildAdded
withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
valueType = snapshot.value;
dispatch_semaphore_signal(sem);
}
withCancelBlock:^(NSError * _Nonnull error) {
NSLog(@"%@", error.localizedDescription);
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return valueType;
}
2 UPDATE:機能ブロックから復帰しないよう
形式を変更。 FIRDatabaseQueryのみを返します。
- (FIRDatabaseQuery *)databaseQuery:(NSString*)ingredient {
__block NSString *valueType = nil;
FIRDatabaseQuery *query = [[_ref child:@"ingredients"] queryEqualToValue:valueType childKey:ingredient];
return query;
}
以下の手順は別の手順です。返される値を除いて、nullです。解決
query = [self databaseQuery:substring];
[query observeEventType:FIRDataEventTypeChildAdded
withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
idValue = snapshot.value;
}
withCancelBlock:^(NSError * _Nonnull error) {
NSLog(@"%@", error.localizedDescription);
}];
NSLog(@"%@", idValue);
メモリに関する問題の詳細を教えてください。どの行/何の例外はありますか? whileループ内でNSRunLoopを実行する代わりに 'dispatch_group_t'を使用しようとしましたか? –
ディスパッチグループtを使ってみることができます。メモリは問題ではなく、アプリケーションの結果がスレッドに固執しているだけです。 –
同じ結果を出した別のアイデアを試してみました。 –