朋友圈的功能,需要显示状态的点赞数和评论数,但是点赞和评论的接口都是 block异步获取,在格式化 model的时候无法正常获取,请问有没有更好的办法 ?

我写的是一朋友圈的功能,需要显示状态的点赞数和评论数,但是点赞和评论的接口都是 block异步获取,在格式化 model的时候无法正常获取,所以想请求解决方法,非常感谢。

-(HxAlbumModel *)factoryModel:(BmobObject *)obj statusType:(StatusType)type{
    hxAlbum *albumOBj = [[hxAlbum alloc] initFromBmobObject:obj];
    NSMutableArray* photos=[NSMutableArray array];
        NSArray * albumPhotos = [obj objectForKey:@"albumPhotos"];
        if (albumPhotos.count !=0) {
            for(NSString * photoUrl in albumPhotos){
                hxAlbumPhoto *photo = [hxAlbumPhoto photoWithOriginUrl:photoUrl thumbnailUrl:[NSString stringWithFormat:@"%@!/format/png",photoUrl]];
                [photos addObject:photo];
            }
        }
//这里格式化 model数据,其中的commentArray和digArray 需要从 block块内异步获取的,这里我就不知道如何操作比较好,所以想问问。非常感谢。
    HxAlbumModel*model = [HxAlbumModel hxAlbuMmodelWithType:Status_ENUM_TYPE fromUser:albumOBj.creator bmobOject:albumOBj avatar:[albumOBj.creator objectForKey:KEY_AVATAR] time:[albumOBj.createdAt stringWithFormat:@"MM-dd HH:mm"] statusID:albumOBj.objectId statusCreateAt:[NSString stringWithFormat:@"%.3lf",[albumOBj.createdAt timeIntervalSince1970]] digArray:albumOBj.toDigs commentArray:albumOBj.toStatusComments contentText:albumOBj.timeline photosArray:photos statusContentRelatedType:nil];
    return model;
}
//查询点赞的关联表
- (void)queryDigsRelation:(NSString*)statusID toDigs:(void(^)(NSMutableArray * toDigs))sucessed{
    //关联对象表
    BmobQuery *bquery = [BmobQuery queryWithClassName:@"_User"];
    //需要查询的列
    BmobObject *post = [BmobObject objectWithoutDataWithClassName:@"hxAlbum" objectId:statusID];
    [bquery whereObjectKey:@"toDigs" relatedTo:post];
    [bquery findObjectsInBackgroundWithBlock:^(NSArray *array, NSError *error) {
        if (error) {
            NSLog(@"%@",error);
        }else{
            [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                BmobObject *user = obj;
                NSLog(@"===%@",[user objectForKey:@"username"]);
            }];
            sucessed([array copy]);
        }
    }];
}

@Stephanie
这是用这异步函数进行尝试编写的,但是我感觉有些地方还需要优化一下。麻烦大佬看下,看看是不是这样搞的,非常感谢。🙏

#pragma mark FindVC下拉刷新
- (void)downloadMoreDataSuccessed:(void(^)(NSMutableArray * modelarray))sucessed
                     downloadModel:(NSMutableArray*)modelArray{
        NSMutableArray * array = [[NSMutableArray alloc]init];
        BmobQuery *query = [BmobQuery queryWithClassName:@"hxAlbum"];
                if (modelArray.count != 0) {
                    HxAlbumModel * model = [modelArray firstObject];
                    NSDictionary *condiction2 = @{@"createdAt":@{@"$gt":@{@"__type": @"Date", @"iso":[self getDateStr:model.createdAts isDown:YES]}}};
                              NSArray *condictonArray = @[condiction2];
                              //作用就是查询创建时间在2014年7月15日到2014年10月15日之间的数据
                              [query addTheConstraintByAndOperationWithArray:condictonArray];
                };
        
            [query orderByDescending:@"createdAt"];
            [query setLimit:10];
            [query includeKey:@"creator,albumPhotos"];
            query.cachePolicy = kBmobCachePolicyNetworkElseCache;
            [query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
                if (!error) {
                    if (results.count != 0) {
                        dispatch_group_t group = dispatch_group_create();
                        dispatch_queue_t queue = dispatch_queue_create("comw", DISPATCH_QUEUE_CONCURRENT);
                        
                        dispatch_group_async(group, queue, ^{
                            dispatch_sync(queue, ^{
                                [results enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                                    dispatch_group_enter(group);
                                    [self factoryModel:obj statusType:Status_ENUM_TYPE blockModel:^(HxAlbumModel * model) {
                                        [array addObject:model];
                                        dispatch_group_leave(group);
                                        NSLog(@"00");
                                    }];
                                }];
                                
                            });
                        });
                         
                        dispatch_group_notify(group, queue, ^{
                            dispatch_async(dispatch_get_main_queue(), ^{
                                NSLog(@"01");
                                sucessed(array);
                          });
                        });
                    }
                }else{
                    [BmobAlbumCloudTools errorlog:error log:@"=====2FindVC获取消息失败=="];
                    NSLog(@"下拉刷新,服务器返回错误:%@",error);
                   sucessed(array);
                }
            }];
}

-(void)factoryModel:(BmobObject *)obj statusType:(StatusType)type blockModel:(void(^)(HxAlbumModel *))sucessed{
    hxAlbum *albumOBj = [[hxAlbum alloc] initFromBmobObject:obj];
    NSMutableArray* photos=[NSMutableArray array];
        NSArray * albumPhotos = [obj objectForKey:@"albumPhotos"];
        if (albumPhotos.count !=0) {
            for(NSString * photoUrl in albumPhotos){
                hxAlbumPhoto *photo = [hxAlbumPhoto photoWithOriginUrl:photoUrl thumbnailUrl:[NSString stringWithFormat:@"%@!/format/png",photoUrl]];
                [photos addObject:photo];
            }
        }
        __block NSMutableArray *temptoDigs;
        __block NSMutableArray *temptoComments;
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t queue = dispatch_queue_create("com.gcd-group.www", DISPATCH_QUEUE_CONCURRENT);
     dispatch_group_enter(group);
     dispatch_group_async(group, queue, ^{
        dispatch_sync(queue, ^{
                [self queryDigsRelation:albumOBj.objectId toDigs:^(NSMutableArray *toDigs) {
                    temptoDigs = toDigs;
                    NSLog(@"22  %@",[NSThread currentThread]);
                    NSLog(@"===%lu",(unsigned long)temptoDigs.count);
                    dispatch_group_leave(group);
                }];
            });
        });
         
        dispatch_group_notify(group, queue, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                HxAlbumModel*model = [HxAlbumModel hxAlbuMmodelWithType:Status_ENUM_TYPE fromUser:albumOBj.creator bmobOject:albumOBj avatar:[albumOBj.creator objectForKey:KEY_AVATAR] time:[albumOBj.createdAt stringWithFormat:@"MM-dd HH:mm"] statusID:albumOBj.objectId statusCreateAt:[NSString stringWithFormat:@"%.3lf",[albumOBj.createdAt timeIntervalSince1970]] digArray:temptoDigs commentArray:@[] contentText:albumOBj.timeline photosArray:photos statusContentRelatedType:nil];
                model.createdAts = obj.createdAt;
                sucessed(model);
            });
        });
    
    
}
阅读 1.5k
avatarAI BotBETA

在你的情况下,由于点赞和评论的数据是异步获取的,而你在格式化 HxAlbumModel 时需要这些数据,你需要调整你的代码结构来适应异步数据的处理。一个常见的做法是使用回调、闭包(block)或者使用响应式编程(如 RxSwift, Combine 等)来管理异步流。

这里,我将展示如何使用闭包(block)来重构你的代码,以便在数据可用时更新你的模型。

重构思路

  1. 修改 factoryModel 方法,使其接受一个完成回调,该回调在异步数据加载完成后被调用。
  2. 在调用 queryDigsRelation 方法时,将结果传递给 factoryModel 的完成回调。

示例代码

首先,修改 factoryModel 方法以接受一个额外的完成回调参数:

typedef void (^HxAlbumModelCompletionBlock)(HxAlbumModel * _Nullable model, NSError * _Nullable error);

- (void)factoryModel:(BmobObject *)obj statusType:(StatusType)type completion:(HxAlbumModelCompletionBlock)completion {
    hxAlbum *albumOBj = [[hxAlbum alloc] initFromBmobObject:obj];
    NSMutableArray *photos = [NSMutableArray array];
    NSArray *albumPhotos = [obj objectForKey:@"albumPhotos"];
    if (albumPhotos.count != 0) {
        for (NSString *photoUrl in albumPhotos) {
            hxAlbumPhoto *photo = [hxAlbumPhoto photoWithOriginUrl:photoUrl thumbnailUrl:[NSString stringWithFormat:@"%@!/format/png", photoUrl]];
            [photos addObject:photo];
        }
    }

    // 初始化模型但不包含点赞和评论
    HxAlbumModel *model = [HxAlbumModel hxAlbuMmodelWithType:Status_ENUM_TYPE fromUser:albumOBj.creator bmobOject:albumOBj avatar:[albumOBj.creator objectForKey:KEY_AVATAR] time:[albumOBj.createdAt stringWithFormat:@"MM-dd HH:mm"] statusID:albumOBj.objectId statusCreateAt:[NSString stringWithFormat:@"%.3lf", [albumOBj.createdAt timeIntervalSince1970]] digArray:@[] commentArray:@[] contentText:albumOBj.timeline photosArray:photos statusContentRelatedType:nil];

    // 异步获取点赞和评论
    [self queryDigsRelation:albumOBj.objectId toDigs:^(NSMutableArray *toDigs) {
        // 假设还有一个方法来获取评论
        [self queryCommentsRelation:albumOBj.objectId toComments:^(NSMutableArray *toComments) {
            // 更新模型
            model.digArray = toDigs;
            model.commentArray = toComments;
            
            // 调用完成回调
            completion(model, nil);
        }];
    }];
}

// 假设的获取评论的方法
- (void)queryCommentsRelation:(NSString *)statusID toComments:(void(^)(NSMutableArray *toComments))sucessed {
    // 这里实现获取评论的逻辑
    // 完成后调用 sucessed
}

注意:

  • factoryModel 现在是一个异步方法,它不会立即返回模型,而是在数据准备好后通过回调返回。
  • 我添加了一个假设的 queryCommentsRelation 方法来模拟获取评论的过程,你需要根据你的实际API来实现它。
  • queryDigsRelation 的回调中,我们调用了 queryCommentsRelation 并在获取到所有需要的数据后更新了模型并调用了完成回调。

这样,你就可以在数据完全加载后处理或显示你的模型了。

2 个回答
- (void)downloadMoreDataSuccessed:(void(^)(NSMutableArray *modelArray))sucessed
                     downloadModel:(NSMutableArray*)modelArray {
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:results.count];
    
    BmobQuery *query = [BmobQuery queryWithClassName:@"hxAlbum"];
    
    if (modelArray.count != 0) {
        HxAlbumModel *model = [modelArray firstObject];
        NSDictionary *condition = @{
            @"createdAt": @{
                @"$gt": @{
                    @"__type": @"Date",
                    @"iso": [self getDateStr:model.createdAts isDown:YES]
                }
            }
        };
        [query addTheConstraintByAndOperationWithArray:@[condition]];
    }
    
    [query orderByDescending:@"createdAt"];
    [query setLimit:10];
    [query includeKey:@"creator,albumPhotos"];
    query.cachePolicy = kBmobCachePolicyNetworkElseCache;
    
    [query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
        if (!error) {
            if (results.count != 0) {
                dispatch_group_t group = dispatch_group_create();
                
                // 初始化数组
                for (NSInteger i = 0; i < results.count; i++) {
                    [array addObject:[NSNull null]];
                }
                
                [results enumerateObjectsUsingBlock:^(BmobObject *obj, NSUInteger idx, BOOL *stop) {
                    dispatch_group_enter(group);
                    [self factoryModel:obj statusType:Status_ENUM_TYPE blockModel:^(HxAlbumModel *model) {
                        if (model) {
                            
                            dispatch_async(dispatch_get_main_queue(), ^{
                                array[idx] = model;
                            });
                        }
                        dispatch_group_leave(group);
                    }];
                }];
                
                dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                    // 移除NSNull对象
                    NSMutableArray *finalArray = [NSMutableArray array];
                    for (id obj in array) {
                        if (![obj isKindOfClass:[NSNull class]]) {
                            [finalArray addObject:obj];
                        }
                    }
                    sucessed(finalArray);
                });
            } else {
                
                sucessed(array);
            }
        } else {
            [BmobAlbumCloudTools errorlog:error log:@"=====2FindVC获取消息失败=="];
            NSLog(@"下拉刷新,服务器返回错误:%@", error);
            sucessed(array);
        }
    }];
}
  1. 在点赞和评论数据从数据库获取后,再初始话model,再去渲染界面 , 这两个查询都是异步的,有一个异步函数dispatch group quen可以实现当这两个异步函数都处理完某些任务后通知你的做model初始化的操作
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏