块、范围和设置变量 Objective C
Posted
技术标签:
【中文标题】块、范围和设置变量 Objective C【英文标题】:Blocks, scoping and setting variables Objective C 【发布时间】:2014-06-11 03:05:08 【问题描述】:我正在使用 AFNetworking AFHTTPSessionManager 发出 GET 请求。当我记录响应对象时,会记录 responseObject。当我尝试记录我的 locationIDsDictionary 时,我得到空值。范围问题? locationIDsDictionary 需要是 _block 类型吗?
viewController.h
@property (strong, nonatomic) NSDictionary *locationIDsDictionary;
viewController.m
[[LPAuthClient sharedClient]GET:getLocationIDString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject)
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;
if (httpResponse.statusCode == 200)
dispatch_async(dispatch_get_main_queue(), ^
_locationArray = responseObject[@"data"];
NSLog(@"Response %@", responseObject);
);
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Failure %@", error);
];
NSLog(@"locationIDsDictionary %@", _locationIDsDictionary);
编辑:输出
Response
data = (
id = 45388148;
latitude = "37.785834";
longitude = "-122.406417";
name = "TESTING HATE VENUE";
,
id = 208947000;
latitude = "37.785834";
longitude = "-122.406417";
name = "The Greatest Isreal";
,
id = 86128772;
latitude = "37.785834";
longitude = "-122.406417";
name = "Pike street";
,
id = 33208867;
latitude = "37.785834";
longitude = "-122.406417";
name = abcde;
,
id = 104267842;
latitude = "37.785834";
longitude = "-122.406417";
name = "somewhere over south dakota";
,
id = 232446516;
latitude = "37.785834";
longitude = "-122.406417";
name = wow;
,
id = 107511313;
latitude = "37.785834";
longitude = "-122.406417";
name = "Yum Yum.com";
,
id = 189736241;
latitude = "37.785834";
longitude = "-122.406417";
name = "wow;l";
,
id = 246109339;
latitude = "37.785834";
longitude = "-122.406417";
name = Fused;
,
id = 153279132;
latitude = "37.785834";
longitude = "-122.406417";
name = 333;
,
id = 115790356;
latitude = "37.785834";
longitude = "-122.406417";
name = "Bar Karma";
,
id = 50341151;
latitude = "37.785834";
longitude = "-122.406417";
name = popoopo;
,
id = 121590347;
latitude = "37.785834";
longitude = "-122.406417";
name = 26;
,
id = 75286586;
latitude = "37.785834";
longitude = "-122.406417";
name = wow;
,
id = 72889805;
latitude = "37.785834";
longitude = "-122.406417";
name = test;
,
id = 284599098;
latitude = "37.785834009";
longitude = "-122.406416997";
name = "Urban Safari";
,
id = 89500038;
latitude = "37.785835266";
longitude = "-122.406417847";
name = "Cali Home";
,
id = 8736810;
latitude = "37.785835266";
longitude = "-122.406417847";
name = "Test%20Test%20Test";
,
id = 45031994;
latitude = "37.78584";
longitude = "-122.4064";
name = japaneses;
,
id = 35874897;
latitude = "37.785806574";
longitude = "-122.406477728";
name = "Hotel Palomar Fifth Floor Restaurant";
);
meta =
code = 200;
;
【问题讨论】:
因为你没有给它赋值? 请出示_locationIDsDictionary的声明,请出示以“Response”开头的完整NSLog输出。 【参考方案1】:以 CrimsonChris 的回答为基础,GET: parameters: success:
方法是异步的。在这段代码中:
[[LPAuthClient sharedClient] GET:getLocationIDString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject)
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;
if (httpResponse.statusCode == 200)
dispatch_async(dispatch_get_main_queue(), ^
_locationArray = responseObject[@"data"];
NSLog(@"Response %@", responseObject);
);
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Failure %@", error);
];
NSLog(@"locationIDsDictionary %@", _locationIDsDictionary);
success
参数是你的完成块,所以:
^(NSURLSessionDataTask *task, id responseObject)
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;
if (httpResponse.statusCode == 200)
dispatch_async(dispatch_get_main_queue(), ^
_locationArray = responseObject[@"data"];
NSLog(@"Response %@", responseObject);
);
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Failure %@", error);
仅在 ios 完成您的下载任务时调用,因此您的字典仅在下载任务完成时被分配。同时,剩余的代码行正在执行,因此异步的含义 - 在不同的线程上执行。如果它是同步的,代码将被暂停,直到该代码块完成,这很糟糕,您会看到它在 iOS 应用程序中被翻译成freezy UI。
所以在执行下载任务时仍会调用 NSLog(@"locationIDsDictionary %@", _locationIDsDictionary);
,因此它将评估为 nil
- 当然,除非您的网速疯狂 :)
【讨论】:
那么我应该在哪里设置 locationIDsDictionary? @noobsmcgoobs 你把它分配在正确的地方,你只是NSLog
把它放在了错误的地方。在它被初始化之前你是NSLog
ging,所以如果你想在分配它之后检查它是否被正确初始化NSLog
它在完成块中。【参考方案2】:
你写...
当我尝试记录我的 locationIDsDictionary 时,我得到了 null。
由于您没有分享此日志的位置,我将假设您正在做这样的事情......
[self runMyGetLocationMethodAsynchronously];
NSLog(@"%@", _locationIDsDictionary);
这不起作用,因为您在 异步 方法的 success 块中设置了 _locationIDsDictionary
。在该块运行之前,不会设置您的字典。
【讨论】:
以上是关于块、范围和设置变量 Objective C的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C autoreleasepool 指令影响范围之外的变量。
从C语言的变量声明到Objective-C中的Block语法