【发布时间】:2011-05-23 23:41:07
【问题描述】:
以下代码下载图像并返回带有块的结果,以便我可以利用块和 Grand Central Dispatch 的异步功能。我发现如果图像或错误对象为零,我会收到 EXC_BAD_ACCESS 错误。如果参数的值为nil,是否总是会导致错误?
失败的部分是用于在方法结束时返回图像的returnImage块。
- (void)downloadImageWithBlock:(void (^)(UIImage *image, NSError *error))returnImage {
dispatch_queue_t callerQueue = dispatch_get_current_queue();
dispatch_queue_t downloadQueue = dispatch_queue_create("Image Downloader Queue", NULL);
dispatch_async(downloadQueue, ^{
UIImage *image = nil;
NSError *error;
// get the UIImage using imageURL (ivar)
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Downloading: %@", imageURL);
});
NSURL *url = [NSURL URLWithString:imageURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLResponse *urlResponse = nil;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
if (!error && response) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Success!");
});
image = [UIImage imageWithData:response];
}
// image will be nil if the request failed
dispatch_async(callerQueue, ^{
returnImage(image, error);
});
});
dispatch_release(downloadQueue);
}
下面是堆栈跟踪,我不知道如何阅读。
0x00002d20 <+0000> push %ebp
0x00002d21 <+0001> mov %esp,%ebp
0x00002d23 <+0003> sub $0x18,%esp
0x00002d26 <+0006> mov 0x8(%ebp),%eax
0x00002d29 <+0009> mov %eax,-0x4(%ebp)
0x00002d2c <+0012> mov -0x4(%ebp),%eax
0x00002d2f <+0015> mov 0x14(%eax),%eax
0x00002d32 <+0018> mov %eax,(%esp)
0x00002d35 <+0021> movl $0x3,0x4(%esp)
0x00002d3d <+0029> call 0x314c <dyld_stub__Block_object_dispose>
0x00002d42 <+0034> mov -0x4(%ebp),%eax
0x00002d45 <+0037> mov 0x18(%eax),%eax
0x00002d48 <+0040> mov %eax,(%esp)
0x00002d4b <+0043> movl $0x3,0x4(%esp)
0x00002d53 <+0051> call 0x314c <dyld_stub__Block_object_dispose>
0x00002d58 <+0056> mov -0x4(%ebp),%eax
0x00002d5b <+0059> mov 0x1c(%eax),%eax
0x00002d5e <+0062> mov %eax,(%esp)
0x00002d61 <+0065> movl $0x7,0x4(%esp)
0x00002d69 <+0073> call 0x314c <dyld_stub__Block_object_dispose>
0x00002d6e <+0078> add $0x18,%esp
0x00002d71 <+0081> pop %ebp
0x00002d72 <+0082> ret
0x00002d73 <+0083> nopw 0x0(%eax,%eax,1)
0x00002d79 <+0089> nopl 0x0(%eax)
【问题讨论】:
-
使调试此代码变得困难的原因是错误不会出现在一行代码中,因此我必须注释掉代码块以尝试确定错误发生的位置。查明错误的代码行很困难。
标签: objective-c grand-central-dispatch objective-c-blocks