Ios 尹及;Yang初始化-在调用init之前等待片段

Ios 尹及;Yang初始化-在调用init之前等待片段,ios,objective-c,grand-central-dispatch,Ios,Objective C,Grand Central Dispatch,假设您有一个在两个单独的块中返回信息的方法,如下所示: @interface SomeObject : NSObject - (instancetype)initWithA:(NSString *)aInfo bInfo:(NSString *)bInfo; @end - (void)someMethod:(void (^)(NSString *aInfo))firstBlock secondBlock:(void (^)(NSString *bInfo))secondBlock

假设您有一个在两个单独的块中返回信息的方法,如下所示:

@interface SomeObject : NSObject
- (instancetype)initWithA:(NSString *)aInfo bInfo:(NSString *)bInfo;
@end

- (void)someMethod:(void (^)(NSString *aInfo))firstBlock
       secondBlock:(void (^)(NSString *bInfo))secondBlock {
  firstBlock(@"a"); secondBlock(@"b");
}
- (void)ourMethod:(void (^)(SomeObject *object))completionBlock {
  SomeObject *someObject = [[SomeObject alloc] initWithA:aInfo bInfo:bInfo];
  [self someMethod:^(NSString *aInfo) {
    //
  } secondBlock:^(NSString *bInfo) {
    //
  }];
  completionBlock(someObject);
}
当两个块都完成时,如何初始化
someObject
并将其传回

假设两个块都是异步执行的


我试图通过摆弄GCD的调度组来解决这个问题,但是,它似乎不是最优的。

您可以使用信号量,但是——一般来说——使异步操作同步是一个危险信号,表明设计不好

这两个块本身是否异步?如果是这样的话,您可以使用
\uu block BOOL firstDone=NO
\u块BOOL secondDone=否
并进行适当的检查,以查看是否是调用completionBlock的时候了。仍然很难看,你需要一个同步原语来确保你不会参加比赛,但这是可行的

如果
firstBlock()
secondBlock()
是同步的并且在同一队列上,那么在第二个队列完成后只需调用
completionBlock()


或者,如果它们是异步且同时调度的,则将它们扔到异步队列上,然后在队列上扔一个障碍块来调用
completionBlock

您可以使用信号量,但一般来说,使异步操作同步是一个红色标志,表明设计不好

这两个块本身是异步的吗?如果是这样的话,您可以使用
\uu block BOOL firstDone=NO
\u块BOOL secondDone=否
并进行适当的检查,以查看是否是调用completionBlock的时候了。仍然很难看,你需要一个同步原语来确保你不会参加比赛,但这是可行的

如果
firstBlock()
secondBlock()
是同步的并且在同一队列上,那么在第二个队列完成后只需调用
completionBlock()


或者,如果它们是异步且同时调度的,则将它们放到异步队列上,然后在调用
完成块的队列上抛出障碍块,因为您需要使用从调用
someMethod
中使用的两个块中获得的值创建
someObject
,调用两个块后,需要创建
someObject

- (void)ourMethod:(void (^)(BOOL initializationComplete))completionBlock {
    __block NSString *a = nil;
    __block NSString *b = nil;

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_group_enter(group);

    [self someMethod:^(NSString *aInfo) {
        a = aInfo;
        dispatch_group_leave(group);
    } secondBlock:^(NSString *bInfo) {
        b = bInfo;
        dispatch_group_leave(group);
    }];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        SomeObject *someObject = [[SomeObject alloc] initWithA:a bInfo:b];
        completionBlock(someObject);
    });
}
这不会阻止
ourMethod
的调用者,并且它确保只有在两个块都完成后才调用完成块


此解决方案假定这两个块是异步运行的。

由于需要使用从调用
someMethod
中使用的两个块中获得的值来创建
someObject
,因此需要在调用这两个块后创建
someObject

- (void)ourMethod:(void (^)(BOOL initializationComplete))completionBlock {
    __block NSString *a = nil;
    __block NSString *b = nil;

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_group_enter(group);

    [self someMethod:^(NSString *aInfo) {
        a = aInfo;
        dispatch_group_leave(group);
    } secondBlock:^(NSString *bInfo) {
        b = bInfo;
        dispatch_group_leave(group);
    }];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        SomeObject *someObject = [[SomeObject alloc] initWithA:a bInfo:b];
        completionBlock(someObject);
    });
}
这不会阻止
ourMethod
的调用者,并且它确保只有在两个块都完成后才调用完成块


此解决方案假定两个块异步运行。

我喜欢屏障块的想法。。。我试试看。
\uu block BOOL
在我看来太难看了。谢谢:)@bbum供参考-这个问题刚刚得到了一个严重的更新,可能会影响你的答案。我喜欢屏障块的想法。。。我试试看。
\uu block BOOL
在我看来太难看了。谢谢:)@bbum仅供参考-这个问题刚刚得到了一个严重的更新,可能会影响你的答案。这与我处理的问题类似。。这个模式的主要问题是从
aInfo
bInfo
初始化
someObject
。不仅仅是调用
completionBlock(YES):)代码
[[NSObject alloc]initWithA:andB:]
甚至无效,但这似乎与您关于在两个块都完成后调用完成块的问题无关。请更新您的问题,并清楚地解释什么是
someObject
,什么是
initWithA:andB
方法,这两个参数应该是什么,以及它与调用
someMethod
的关系。这是有效的。。。如果
firstBlock
包含多个变量,所有这些变量都需要传递给
SomeObject
,您会有什么不同?您是否会在范围之外添加更多的
\u block
变量?有什么更好的主意?要支持从
firstBlock
secondBlock
返回的任意数量的变量@这是一个全新的问题。现在就按照这个答案中的模式来做。如果你认为有一种更好的方法来处理一组特定的工作代码,请考虑发布一个类似于我所处理的代码审查。这个模式的主要问题是从
aInfo
bInfo
初始化
someObject
。不仅仅是调用
completionBlock(YES):)代码
[[NSObject alloc]initWithA:andB:]
甚至无效,但这似乎与您关于在两个块都完成后调用完成块的问题无关。请更新您的问题,并清楚地解释什么是
someObject
,什么是
initWithA:andB
方法,这两个参数应该是什么,以及它与调用
someMethod
的关系。这是有效的。。。如果
firstBlock
包含多个变量,所有这些变量都需要传递给
SomeObject
,您会有什么不同?您是否会在范围之外添加更多的
\u block
变量?有什么更好的主意?要支持从
firstBlock
secondBlock
返回的任意数量的变量@这是一个全新的问题。现在请按照这个答案中的模式进行操作。如果您以后认为可能有更好的方法来处理特定的一组工作代码,请考虑发布代码审查。