0

を返すこのメソッドを作成しようとしていますNSArray。私のNSMutableArray(friendUsers)はオブジェクトを正しく追加しますが、dispatch_asyncの外では配列は空です。ユーザーをメイン キューに追加しようとしましたが (ashowed のように)、配列が空です。何か案は ?ご助力いただきありがとうございます。

- (NSArray *)checkUsersInGroup {

    NSMutableArray *friendUsers = [[NSMutableArray alloc] init];

    dispatch_queue_t checkUSers = dispatch_queue_create("CheckUsers", NULL);
    dispatch_async(checkUSers, ^{

        NSArray *totalUsers = [VVDataRead lecturaDades];
        NSArray *usersToSearch = [_grup objectForKey:@"groupFriends"];

        for (NSString *tempUserId in usersToSearch){
            for (NSDictionary *user in totalUsers){
                NSString *id = [user objectForKey:@"id"];
                    if ([tempUserId isEqualToString:id])
                        dispatch_async(dispatch_get_main_queue(), ^{
                            [friendUsers addObject:user];
                        });
            }
        }

    });
    NSLog(@"people:%@",friendUsers);
    return [friendUsers copy];
}
4

2 に答える 2

3

ブロックを使用すると、この場合の作業が楽になります。

- (void)checkUsersInGroupWithCompleteBlock:(void(^)(NSMutableArray * resultArray))completeBlock {

    NSMutableArray *friendUsers = [[NSMutableArray alloc] init];

    dispatch_queue_t checkUSers = dispatch_queue_create("CheckUsers", NULL);
    dispatch_async(checkUSers, ^{

        NSArray *totalUsers = [VVDataRead lecturaDades];
        NSArray *usersToSearch = [_grup objectForKey:@"groupFriends"];

        for (NSString *tempUserId in usersToSearch){
            for (NSDictionary *user in totalUsers){
                NSString *id = [user objectForKey:@"id"];
                if ([tempUserId isEqualToString:id])
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [friendUsers addObject:user];
                    });
            }
        }

        // call the complete block with the result when you finished
        if (completeBlock) completeBlock(friendUsers);
    });
}

...そして、メソッドを呼び出す方法は次のとおりです。

- (void)anyMethod {

    // ... do whetever you want here before

    [self checkUsersInGroupWithCompleteBlock:^(NSMutableArray *resultArray) {
        NSLog(@"%@", resultArray);
    }];

    // ... or after

}

編集:

注:これは別の可能な解決策ですが、あなたの場合はメインスレッドを一時停止するだけなので(これは間違いなく悪いです)、この解決策では何も得られませんが、メインスレッドに痛みがありますが、2つのバックグラウンドスレッドを使用している場合、このソリューションは、スレッド間の同期の非常に良い例を提供できます。

- (NSArray *)checkUsersInGroup {

    NSMutableArray *friendUsers = [[NSMutableArray alloc] init];

    // our semaphore is here
    dispatch_semaphore_t _semaphore = dispatch_semaphore_create(0);

    dispatch_queue_t checkUSers = dispatch_queue_create("CheckUsers", NULL);
    dispatch_async(checkUSers, ^{

        NSArray *totalUsers = [VVDataRead lecturaDades];
        NSArray *usersToSearch = [_grup objectForKey:@"groupFriends"];

        for (NSString *tempUserId in usersToSearch){
            for (NSDictionary *user in totalUsers){
                NSString *id = [user objectForKey:@"id"];
                if ([tempUserId isEqualToString:id])
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [friendUsers addObject:user];
                    });
            }
        }
        // the process finished
        dispatch_semaphore_signal(_semaphore);

    });

    // ... we are wainitng for the semaphore's signal
    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
    dispatch_release(_semaphore);

    NSLog(@"people:%@",friendUsers);
    return [friendUsers copy];

}
于 2013-01-11T12:32:36.690 に答える
0

これを解決するには多くの戦略がありますが、操作がバックグラウンド スレッドで行われるため、配列を返すことはその 1 つではありません。を使用NSNotificationCenterして、タスクが終了したことを通知し、配列を読み取ることができます。すなわち

- (void)checkUsersInGroup {

    NSMutableArray *friendUsers = [[NSMutableArray alloc] init];

    dispatch_queue_t checkUSers = dispatch_queue_create("CheckUsers", NULL);
    dispatch_async(checkUSers, ^{

        NSArray *totalUsers = [VVDataRead lecturaDades];
        NSArray *usersToSearch = [_grup objectForKey:@"groupFriends"];

        for (NSString *tempUserId in usersToSearch){
            for (NSDictionary *user in totalUsers){
                NSString *id = [user objectForKey:@"id"];
                    if ([tempUserId isEqualToString:id])
                        dispatch_async(dispatch_get_main_queue(), ^{
                            [friendUsers addObject:user];
                        });
            }
        }

        // Signal background task is finished
        // Make sure to add an observer to this notification
        [[NSNotificationCenter defaultCenter] postNotificationName:@"friendsAddLiteral"
                                                                object:nil];

    });
}

//this method will respond to the notification
- (void) onFriendsAdded:(NSNotification*)notif {
    //do something on the main thread
}
于 2013-01-11T11:14:25.593 に答える