Должен ли NSPurgeableData многократно использоваться после удаления его содержимого?

У меня есть код, использующий NSPurgeableData это работало, пока использование памяти моей машины не стало высоким, и в этот момент я начал получать исключение. Это сообщение в исключении:

*** Завершение работы приложения из-за невыполненного исключения "NSGenericException", причина: "*** -[Длина NSPurgeableData]: доступ осуществлен вне успешных вызовов -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 ответов

Другие вопросы по тегам