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

时间:2016-05-12 14:26:12

标签: 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调用它并将nil作为参数发送?

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

我对ObjC中的block不太熟悉。任何人都可以提示吗?

3 个答案:

答案 0 :(得分:1)

是的,你是对的。它调用自身并发送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
        }

    }];

答案 1 :(得分:0)

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

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) {...};

here

了解更多相关信息

答案 2 :(得分:0)

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

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

[MyClass getProfile:^(NSString * message){

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

[MyClass getProfile:nil];

如果这样使用,当getProfile完成其工作时,你更愿意不做任何事情。

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