使用 ALAssetsLibrary assetForURL:resultBlock:failureBlock: EXC_BAD_ACCESS 错误:

发布于 2024-11-07 21:06:51 字数 2760 浏览 0 评论 0原文

我正在尝试从用户选择的图像中读取 EXIF 数据。我为此使用 ALAssetLibrary。到目前为止,我已经成功获取了assetForURL:resultBlock:failureBlock:方法所需的参考URL,但是当我尝试使用参考URL执行任何操作时,我得到了EXC_BAD_ACCESS 错误。

URL 的 NSLog 在使用之前会生成(据我所知是正确的)字符串:

assets-library://asset/asset.JPG?id=1000000003&ext=JPG

我一直在试图解决这个问题,但我似乎每次都陷入了死胡同。我必须承认我对 Objective-C 总体来说还是个新手,所以请随意批评我的代码。

代码(距离完整的类还很远,但我认为应该足够了):

//Class_X.m

-(void)readExifDataFromSelectedImage:(NSURL *)imageRefURL    
{
    void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset)
    {
       NSLog(@"Test:Succes");
    };

    ALAssetsLibrary *myAssetLib;
    NSLog(@"%@",imageRefURL);
    [myAssetLib assetForURL:imageRefURL
                resultBlock:ALAssetsLibraryAssetForURLResultBlock 
               failureBlock:^(NSError *error){NSLog(@"test:Fail");}];
}

//Class_Y.m
//This  also conforms to the UIImagePickerControllerDelegate And the NavigationControllerDelegate protocols:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    self.referenceURL = [info valueForKey:@"UIImagePickerControllerReferenceURL"];
    NSString *mediaType = [info
                       objectForKey:UIImagePickerControllerMediaType];
    [self dismissModalViewControllerAnimated:YES];
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
        imageView.image = selectedImage;
        btnNoPicture.hidden = YES;
        btnSelectPicture.hidden = YES;
        btnTakePicture.hidden = YES;
        imageView.hidden = NO;
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Use this image?" 
                                                        message:@"Are you sure you want to use this image?" 
                                                       delegate:self 
                                              cancelButtonTitle:@"No" 
                                              otherButtonTitles:@"Yes", nil];
        [alert show];
        [alert release];
    }

}


-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0)
    {
        //Do not use the selected image.
        imageView.image = nil;
        imageView.hidden = YES;
        //Restart picking process
    }
    else
    {

        // I have an instance variable of type Class_X which i use 
        // throughout this class; let's call this variable "report". 
        // I also have the referenceURL stored as an instance variable.
        [self.report readExifDataFromSelectedImage:self.referenceURL];
    }

}

I'm trying to read the EXIF data from an image, selected by a user. I'm using the ALAssetLibrary for this. So far I've managed to get the reference URL needed for the assetForURL:resultBlock:failureBlock: method, but when I try to do anything with the reference URL i get a EXC_BAD_ACCESS error.

An NSLog of the URL, right before using it, results in the (correct, as far as i know) string:

assets-library://asset/asset.JPG?id=1000000003&ext=JPG

I've been trying to figure this out, but I seem to be hitting a dead end each time. I must admit I'm new to Objective-C in general, so please feel free to criticize my code accordingly.

Code (far from the complete classes, but i think it should be sufficient):

//Class_X.m

-(void)readExifDataFromSelectedImage:(NSURL *)imageRefURL    
{
    void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset)
    {
       NSLog(@"Test:Succes");
    };

    ALAssetsLibrary *myAssetLib;
    NSLog(@"%@",imageRefURL);
    [myAssetLib assetForURL:imageRefURL
                resultBlock:ALAssetsLibraryAssetForURLResultBlock 
               failureBlock:^(NSError *error){NSLog(@"test:Fail");}];
}

//Class_Y.m
//This  also conforms to the UIImagePickerControllerDelegate And the NavigationControllerDelegate protocols:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    self.referenceURL = [info valueForKey:@"UIImagePickerControllerReferenceURL"];
    NSString *mediaType = [info
                       objectForKey:UIImagePickerControllerMediaType];
    [self dismissModalViewControllerAnimated:YES];
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
        imageView.image = selectedImage;
        btnNoPicture.hidden = YES;
        btnSelectPicture.hidden = YES;
        btnTakePicture.hidden = YES;
        imageView.hidden = NO;
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Use this image?" 
                                                        message:@"Are you sure you want to use this image?" 
                                                       delegate:self 
                                              cancelButtonTitle:@"No" 
                                              otherButtonTitles:@"Yes", nil];
        [alert show];
        [alert release];
    }

}


-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0)
    {
        //Do not use the selected image.
        imageView.image = nil;
        imageView.hidden = YES;
        //Restart picking process
    }
    else
    {

        // I have an instance variable of type Class_X which i use 
        // throughout this class; let's call this variable "report". 
        // I also have the referenceURL stored as an instance variable.
        [self.report readExifDataFromSelectedImage:self.referenceURL];
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮世清欢 2024-11-14 21:06:51

EXC_BAD_ACCESS 通常是过度释放对象(悬空指针)的结果。由于库异步运行,您的块在 readExifDataFromSelectedImage: 方法返回后执行,因此此时 imageRefURL 可能已经被释放。尝试在请求资产之前保留 URL,并在成功和失败块中释放它。

EXC_BAD_ACCESS is most often the result of an over-released object (dangling pointer). As the library operates asynchronously, your block is executed after the readExifDataFromSelectedImage: method has returned, so imageRefURL is probably already deallocated at this point. Try to retain the URL before requesting the asset and release it in the success and failure blocks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文