【问题标题】:How to access a variable inside the block of id type in Objective-C? [duplicate]如何访问Objective-C中id类型块内的变量? [复制]
【发布时间】:2016-08-18 02:26:48
【问题描述】:

搜索此类错误后:

变量不可赋值(缺少 __block 类型说明符)

我找到了以下解决方案 Assign a variable inside a Block to a variable outside a Block,在阅读了 __block 之后,我无法从接受的答案中受益,而且我的代码是不同的场景。

这是我正在使用的代码:

NSDictionary *strongUser = [[NSDictionary alloc]init];
__block  NSDictionary *user = strongUser;

NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:@"id, name, email" forKey:@"fields"]; 
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters]
    startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
        user = result;
}];

NSLog(@"%@",user);

NSLog什么都不打印

我想要的是将结果值赋予块外的外部变量。

【问题讨论】:

  • 你的完成处理程序呢,它完成了吗?
  • 我的完成处理程序完成
  • 好的,'result'参数就是你想要的?
  • 我认为您对异步代码中运行的顺序感到困惑。您应该将 API 调用下方的所有代码移动到您从完成块调用的单独方法中。将结果传递给该方法。
  • 是的,你现在我明白了

标签: ios objective-c


【解决方案1】:

我建议使用__block NSDictionary *strongUser。我担心指针user 仍然存在于块内,但它指向的基础变量可能不再可访问。例如:

__block NSDictionary *strongUser = [[NSDictionary alloc]init];

NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:@"id, name, email" forKey:@"fields"]; 
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters]
 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error)
 {
     strongUser = result;
 }];

【讨论】:

  • 你能提供详细的答案吗?
  • 我试过你的解决方案同样的问题仍然存在
【解决方案2】:

在您的块中添加以下

NSLog(@"Doing assignment inside the block");

然后运行您的代码。

你的问题的答案是显而易见的。

HTH

【讨论】:

  • 我听不懂你想说什么
  • 运行代码时,两条日志语句的打印顺序是什么?
  • 块外的日志在块内运行之前运行我知道但我想要一个解决方案
  • 解决方案 - 使用属性,而不是局部变量。或者等待异步块完成。
  • 这就是异步编程的本质。有多种方法可以处理该问题。您可以从块中调用完成/继续块,传递结果;您可以使用信号量等待完成;等等,等等。您需要阅读异步设计并选择适合您场景的解决方案。 HTH
【解决方案3】:

您异步运行代码,并在完成处理程序之前评估您的日志。
将您的日志直接添加到完成处理程序的范围内。

NSDictionary *strongUser = [[NSDictionary alloc]init];
__block  NSDictionary *user = strongUser;

NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setValue:@"id, name, email" forKey:@"fields"]; 
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters]
 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error)
 {
     user = result;

     NSLog(@"%@",user);
 }];

【讨论】:

  • 是的,已经在 developer.apple.com/library/ios/documentation/Cocoa/Conceptual/… 上读到过这个,但是我该如何解决我的问题
  • 查看我更新的代码 sn-p。
  • 块内的日志给了我结果,但我想在块外访问这些值
  • 只有在完成处理程序完成后才能访问它,因为“startWithCompletionHandler”是异步运行的。尝试创建“strongUser”,而不是作为局部变量,而是作为属性 - 这样它将在您的类范围内可见。
【解决方案4】:

你有一个局部变量 strongUser,这意味着当这个作用域(函数)完成时,你的局部变量 strongUser 将被释放 - 所以当你的块工作时 __block variavle 用户是活动的,但它指向不存在的对象。

实现它的简单方法是使用惰性设置器创建一个属性:

@property (nonatomic, strong) NSDictionary *strongUser;

- (NSDictionary *)strongUser {
    if (!_strongUser) {
        _strongUser = [[NSDictionary alloc] init];
    }
    return _strongUser;
}

并用 selfinside 块调用它:

    NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
    [parameters setValue:@"id, name, email" forKey:@"fields"];

    [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me"parameters:parameters]
 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
     self.strongUser = result;  
     NSLog(@"%@",self.strongUser);  
     }];

希望对你有帮助!

【讨论】:

  • 同样的问题仍然存在:S
  • @ZakariaDarwish 您不会在最后一行的 NSLog 中获得 result 的值,因为它在完成块之前工作。完成后,结果的值将设置在 strongUser 中。
  • 你能告诉我如何知道何时完成
  • 这是该行工作的范围:self_.strongUser = result;
  • 我会更新代码也许我的问题会更清楚
猜你喜欢
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多