NSPurgeableData在其内容被丢弃后是否可以重用?

时间:2015-06-04 00:35:18

标签: objective-c cocoa memory-management nsdata nsmutabledata

我有一些使用NSPurgeableData的代码正常工作,直到我的机器的内存使用量开始变高,此时我开始抛出异常。这是例外中的消息:

  

***由于未捕获的异常'NSGenericException'终止应用程序,原因:'*** - [NSPurgeableData length]:在成功的-beginContentAccess和-endContentAccess调用之外访问。'

这是我的代码的本质:

- (NSImage *)imageProperty {
    if (!self.purgeableImage || ![self.purgeableImage beginContentAccess]) {
        if (!self.purgeableImage) {
            self.purgeableImage = [NSPurgeableData data];
        }

        NSImage *image = // Get the image

        // THIS LINE CAUSES THE EXCEPTION
        [self.purgeableImage setData: image.TIFFRepresentation];
    }
}

- (void)clearImage {
    [self.purgeableImage endContentAccess];

    // Putting in this line works, but shouldn't be necessary, should it?
    //self.purgeableImage = nil
}

clearImage与对imageProperty的调用保持平衡。我可以用这个测试用例重现异常:

- (void)testImageProperty_CallTwiceWithMemoryPressure {
    MyClass *instance = // Initialize the sucker

    NSImage *image = instance.imageProperty;
    NSPurgeableData *purgeableData = image.purgeableImage;

    XCTAssertNotNil(image, @"Image not loaded");
    XCTAssertEqual(image.size.width, (CGFloat)988, @"Image loaded with incorrect width");
    XCTAssertEqual(image.size.height, (CGFloat)1500, @"Image loaded with incorrect height");

    [instance clearImage];

    // Discard, as if there were memory pressure
    [purgeableData discardContentIfPossible];
    XCTAssertTrue(purgeableData.isContentDiscarded, @"Failed to simulate memory pressure");

    // TRIGGERS THE EXCEPTION
    image = instance.imageProperty;
    XCTAssertNotNil(image, @"Image not loaded on second attempt");
}

我可以通过取消注释-clearImage中的第二行来消除异常,但我不认为这是必要的。在原始数据被丢弃后,我不能继续使用NSPurgeableData对象吗?

更新:其他解决方法

调用-endContentAccess后将其缩小的问题是该类有效地不提供缓存。我找到的另一个解决方案是更新前导if语句,如下所示:

    if (!self.purgeableImage || self.purgeableImage.isContentDiscarded || ![self.purgeableImage beginContentAccess]) {
        if (!self.purgeableImage || self.purgeableImage.isContentDiscarded) {

0 个答案:

没有答案