关于ios:将__block参数传递给类方法(用于获取请求)

passing __block parameters to class method (for get request)

我想创建以下类方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+(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);
    }
}

两个问题:

  • 我收到以下错误:变量不可分配(丢失
    __block类型说明符)如何将块设置为方法参数?
  • 如何调用此函数我应该使用&self.setMe传递变量吗?

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

    相反,您应该使用调用程序可用于设置ivar的完成块来处理此问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    + (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);
        }
    }

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

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

    现在,如果self被破坏,weakSelf将变为零,因此回调将基本上是一个无操作。

    这有一个额外的好处,就是不需要通过引用传递ivar指针,你会注意到,在iOS框架中根本不会发生这种情况(NSError是我能想到的唯一例外)。


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