【问题标题】:passing __block parameters to class method (for get request)将 __block 参数传递给类方法(用于获取请求)
【发布时间】:2015-02-03 23:55:50
【问题描述】:

我想创建以下类方法:

+(void) getValue4Key:(NSString*)p_key andSet:(id)p_variable
{    
    NSString *baseURLString = <<myURL>>;
    @try{
        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        [manager GET:baseURLString
          parameters:nil
             success:^(AFHTTPRequestOperation *operation, id responseObject) {
                 NSDictionary* element = responseObject[0];
                 element = [element objectForKey:@"fields"];

                 p_variable = [element objectForKey:@"value"];
             }
             failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                 NSLog(@"getSystemVariableKey error: %@",error);
             }];
    }
    @catch (NSException *exception) {
        NSLog(@"exception %@", exception);
    }
}

两个问题:

  1. 我收到以下错误:变量不可分配(缺少 __block 类型说明符)如何为方法参数设置块?
  2. 如果我用&amp;self.setMe传递变量,如何调用这个函数?

【问题讨论】:

  • 不要在 ARC 下使用异常,直到你知道你做了什么,你不知道。

标签: ios objective-c objective-c-blocks get-request


【解决方案1】:

我认为通过引用传递 ivar 以在以后异步设置的方法不是一个好方法。如果对象(在问题#2 中称为self.setMe 中的self)在请求完成之前被销毁怎么办?你会随机崩溃。

相反,您应该使用调用者可以用来设置 ivar 的完成块来解决此问题:

+ (void)getValue4Key:(NSString*)p_key 
      withCompletion:(void (^)(id value))completion
{    
    NSString *baseURLString = <<myURL>>;
    @try{
        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        [manager GET:baseURLString
          parameters:nil
             success:^(AFHTTPRequestOperation *operation, id responseObject) {
                 NSDictionary* element = responseObject[0];
                 element = [element objectForKey:@"fields"];

                 id value = [element objectForKey:@"value"];
                 if (completion) {
                     completion(value);
                 }
             }
             failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                 NSLog(@"getSystemVariableKey error: %@",error);
                 if (completion) {
                     completion(nil);
                 }
             }];
    }
    @catch (NSException *exception) {
        NSLog(@"exception %@", exception);
    }
}

然后你会这样调用这个函数:

YourObject *__weak weakSelf = self;
[YourObject getValue4Key:@"your_key" completion:^(id value){
    weakSelf.setMe = value;
}];

现在,如果 self 被销毁,weakSelf 将变为 nil,因此回调基本上是空操作。

这具有不需要通过引用传递 ivar 指针的额外优势,您会注意到,这在 iOS 框架中根本不经常发生(NSError 是我能想到的唯一例外)。

【讨论】:

    【解决方案2】:

    p_variable是参数,是函数的局部变量。您的块在某些操作结束时异步运行。当块运行时,getValue4Key:andSet: 已经返回很久了。因此,即使您可以设置p_variable 变量,也没有人可以使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2016-04-01
      • 2012-01-13
      • 1970-01-01
      • 2013-02-20
      相关资源
      最近更新 更多