Objective-C 块不返回并在块中调用它自己?



我正在学习开发iOS应用程序,现在我正在阅读一些Objective-C源代码。

这是一种获取用户配置文件的方法。

+ (void)getProfile:(void (^)(NSString *message))completion {
    NSDictionary *dic = @{@"module":@"profile"};
    [[self defaultManager] POST:KBaseUrl parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([self jsonOKForResponseObject:responseObject] && [self checkLogin:responseObject]) {
            [ProfileManager sharedInstance].rank = responseObject[@"Variables"][@"space"][@"group"][@"grouptitle"];
            [ProfileManager sharedInstance].credit = responseObject[@"Variables"][@"space"][@"credits"];
            [ProfileManager sharedInstance].gender = responseObject[@"Variables"][@"space"][@"gender"];
            completion(nil);
        } else {
            completion(@"fail");
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        completion(@"fail");
    }];
}

我的问题是关于completion块。

我假设completion块返回void并接收NSString参数。

在块中,completion(nil)是什么意思

这是否意味着块completion调用它self并将nil作为参数发送?

这与参数的类型NSString*不冲突吗?

我对ObjC中的block不太熟悉。有人能给个提示吗?

是的,你是对的。它调用自己并将nil作为参数发送,并且它与NSString参数不冲突。您只是将nil传递给NSString参数。

您可以调用上面的方法,如:

[YourClass getProfile:^(NSString *message) {
       //message will be nill if you pass completion(nil);
}];

因此,当您在完成块中传递nill时,上面方法调用中的消息将为nil!

完成块是通知您方法调用已完成,此时您可以让该方法通过某些参数,如果我们考虑您的方法:

+ (void)getProfile:(void (^)(NSString *message))completion {
    NSDictionary *dic = @{@"module":@"profile"};
    [[self defaultManager] POST:KBaseUrl parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([self jsonOKForResponseObject:responseObject] && [self checkLogin:responseObject]) {
           .....
            completion(@"hey sucess");
        } else {
            completion(@"if loop failed");
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        completion(@"some error occured");
    }];
}

当您调用方法getProfile:时

[YourClass getProfile:^(NSString *message) {
       //Execution will reach here when the method call for getPRofile is complete and you have a result which you just sent through the completion block as a parameter which is a string  and is waiting for you to process.
      //you can do more from here
         if([message isEqualToString:@"hey success"]){
                //do something
         }
          if([message isEqualToString:@"if loop failed"]){
                //do something
         }
         if([message isEqualToString:@"some error occured"]){
                //do something
         }
}];

根据@rmaddy的评论,使用BOOL来指示状态成功或失败总是一个很好的做法,而不是依赖于字符串,因为字符串可以被本地化/更改。我们将使用该字符串来获得有关该错误的更多描述。所以你的区块应该是:

+ (void)getProfile:(void (^)(BOOL status,NSString *message))completion {
      .....
      completion(YES,@"hey success");
}

你可以这样称呼它":

[YourClass getProfile:^(BOOL status, NSString *message) {
        if(status){
               //get the success message 
         }else{
              //get the fail message
        }
    }];

块有很多类型,比如:-作为局部变量:

returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
    As a property:
@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes);

作为方法参数:

- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;

作为方法调用的参数:

[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];

作为typedef:

typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};

从这里阅读更多关于的信息

完成块不返回任何内容。这只是一段要执行的代码,仅此而已。不过,您可以在调用它的地方给它一些输入,这样您就可以在其他地方使用结果。

NSString*消息是块的输入,因此当您将函数getProfile调用为:时

[MyClass getProfile:^(NSString*消息){

//编写要在getProfile函数完成其工作并在此处发送消息时执行的代码
}];

[MyClass getProfile:nil];

当这样使用时,当getProfile完成其工作时,您宁愿不做任何事情。

您可能将网络管理器功能的完成块与您编写的块混合在一起。

相关内容

最新更新