我正在学习开发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完成其工作时,您宁愿不做任何事情。
您可能将网络管理器功能的完成块与您编写的块混合在一起。