0

我正在尝试编写返回NSArray. 我的NSMutableArray(friendUsers)正确添加了对象,但在 dispatch_async 之外,数组是空的。我尝试将用户添加到主队列中(如图所示),但数组为空。有任何想法吗 ?感谢你的帮助。

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

}

编辑:

注意:这是另一种可能的解决方案,但在您的情况下,它只是暂停主线程(这绝对是不好的),因此您不会通过此解决方案获得任何收益,但主线程会很痛苦,但如果您在两个后台线程上,这个解决方案可以给出线程之间同步的一个很好的例子。

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

有很多策略可以解决这个问题,但是由于您的操作发生在后台线程上,因此返回数组不是其中之一。您可以NSNotificationCenter用来表示任务已完成并读取数组。IE

- (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 回答