托管对象属性上的EXC_BAD_ACCESS

时间:2014-11-08 15:29:50

标签: ios objective-c pdf core-data nsfetchedresultscontroller

我在当前的项目中遇到了问题。

目标是下载pdf文件并将其显示在UIPageViewController中。 用户可以通过UICollectionView滚动浏览可用的pdf,UICollectionView由NSFetchedResultsController提供数据。

如果触发了读取按钮,则将受管对象传递给ViewController 检查pdf是否已下载或是否需要下载,然后显示。

此代码负责加载新的View Controller并将Managed Object传递给它。

- (IBAction)readNowButtonPressed:(UIButton *)sender
{

    UICollectionViewCell *cell = (UICollectionViewCell*)[[sender superview] superview];
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:cell.tag inSection:0];
    EPaper *epaper = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if (epaper) {

        DHEPaperLoadingViewController  *epaperLoadingViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"epaperLoadingController"];
        epaperLoadingViewController.epaper = epaper;
        epaperLoadingViewController.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:epaperLoadingViewController animated:YES];
    }

}

此代码位于新View Controller的viewDidLoad方法中,并决定如何处理数据。

if (self.epaper.pdfData) {
        [self createPDFForData:self.epaper.pdfData];
        [self displayPDF];
    }
    else {
        [DHDownloadHelper downloadPDFWithRequest:[self createURLRequest]];

        __weak DHEPaperLoadingViewController *weakSelf = self;
        EPaper *currentEpaper = self.epaper;
        [[NSNotificationCenter defaultCenter] addObserverForName:EPAPER_DOWNLOAD_PROGRESS_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
            NSDictionary *userInfo = note.object;
            float progress = [[userInfo objectForKey:EPAPER_DOWNLOAD_PROGRESS] floatValue];
            weakSelf.progressBar.progress = progress;
        }];

        [[NSNotificationCenter defaultCenter] addObserverForName:EPAPER_DOWNLOAD_FINISHED_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
            NSDictionary *userInfo = note.object;
            NSData *data = [userInfo objectForKey:EPAPER_DOWNLOAD_DATA];
            currentEpaper.pdfData = data;


            [currentEpaper.managedObjectContext save:nil];
            [weakSelf createPDFForData:data];
            [weakSelf displayPDF];
        }];
    }
}

在大多数情况下这很好用。但是有一种情况,EXC_BAD_ACCESS似乎发生在这一行:

if (self.epaper.pdfData) //EXC_BAD_ACCESS

此错误在以下情况下发生,可以重现:

  • 同一项目已触发读取按钮3次(可触发一次,下载正确,可触发) 再次,它显示正确的PDF,而无需再次下载,但 它第三次崩溃了)
  • 下载并正确显示了一个pdf,另一个项目需要 下载

据我所知,当一个对象已经被释放时会发生EXC_BAD_ACCESS, 但我有一个强大的指针,并检查它是否响应属性选择器(这是)。我还确保代码在主线程上执行。

还有什么可能导致这个问题?

提前谢谢。

1 个答案:

答案 0 :(得分:0)

你可以试试这个

if (self.epaper && self.epaper.pdfData) 

但我不确定这是否会隐藏另一个问题。

您是否也将自己视为这些通知的观察者?来自文档...

  

您必须在addObserverForName指定的任何对象之前调用removeObserver:或removeObserver:name:object:object:queue:usingBlock:is deallocated。