приложение вылетает при завершении IKSlideshow; то же самое происходит с простым примером приложения

#objective-c #cocoa #macos #sdk #slideshow

#objective-c #cocoa #macos #sdk #слайд-шоу

Вопрос:

У меня есть довольно маленькое приложение, которое показывает фотографии, хранящиеся на веб-сервере, которое вылетает при завершении его части слайд-шоу. Я использую IKSlideshow. Чтобы проиллюстрировать проблему, я написал новое приложение, которое больше ничего не делает, и оно тоже вылетает. Вот новое приложение. Большая часть кода была сгенерирована автоматически Xcode 4. Использование SDK 10.6, предназначенного для 10.6, работающего на 10.6, компилятор LLVM 2.0, 64-разрядный. Пробовал 32-разрядную версию, LLVM GCC 4.2, 10.5 SDK — все в разных комбинациях, и то же самое.

Вот файл заголовка:

 #import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>

@interface SlideshowTestAppDelegate : NSObject <NSApplicationDelegate, IKSlideshowDataSource> {
@private
    NSWindow *window;
}

@property (assign) IBOutlet NSWindow *window;
- (IBAction)action:(id)sender;

@end
  

и вот файл реализации:

 #import "SlideshowTestAppDelegate.h"

@implementation SlideshowTestAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
}

- (NSUInteger)numberOfSlideshowItems
{
    return 20;
}

- (id)slideshowItemAtIndex:(NSUInteger)index
{
    static NSURL *url = nil;
    if (url == nil)
        url = [[NSURL URLWithString:@"http://basepath.com/galleries/Anne U. White Trail/MJR_20070519_0537.jpg"] retain];
    return url; // show the same image over and over
}

- (IBAction)action:(id)sender
{
    [[IKSlideshow sharedSlideshow] runSlideshowWithDataSource:self inMode:IKSlideshowModeImages options:[NSDictionary dictionary]];
}

@end
  

Чтобы запустить слайд-шоу, вы выбираете File-New, который вызывает метод action. Затем, во время запуска слайд-шоу (оно запускается с паузой), вы нажимаете стрелку вправо на элементах управления слайд-шоу на экране 10 раз так быстро, как только можете, а затем вводите Esc или нажимаете X. Приложение каждый раз вылетает. Информация при сбое меняется, но несколько раз оно вылетает с этим сообщением на консоли:

SlideshowTest(3882,0x7fff702e6ca0) malloc: * ошибка для объекта 0x10056f110: освобождаемый указатель не был выделен * установите точку останова в malloc_error_break для отладки

Но диагностический вывод, который я получаю при сбое, не соответствует.

Я использую одно и то же изображение для всех 20 слайдов только для того, чтобы упростить выполнение этого примера. В моем реальном приложении все слайды разные.

Даже если вы быстро нажимаете вперед, слайд-шоу не должно вылететь. Я не ожидаю, что мои пользователи будут это делать, но в моем реальном приложении это приводит к сбою приложения после просто запуска на некоторое время (10 мин. скажем), никогда, когда слайд-шоу действительно запущено, но только когда я завершаю его. (Никаких переходов вперед; опять же, это просто способ, который я придумал, чтобы легко воспроизвести сбой.)

Это такое простое приложение, что мне трудно поверить, что какие-либо данные были выделены мной неправильно или что-либо не сохранено.

У кого-нибудь еще были проблемы со сбоем IKSlideshow? Кто-нибудь видит что-нибудь, чего я не вижу?

Спасибо!

Марк

ОБНОВЛЕНИЕ: Подумав, что, возможно, делегат слайд-шоу и делегат приложения не должны быть одним и тем же объектом, я создал новый объект, который будет служить только делегатом слайд-шоу, создал его экземпляр и использовал его. Тот же сбой, что и раньше.

Комментарии:

1. У меня есть подозрение, что IKSlideshow может не поддерживать удаленные URL-адреса. В документации ничего не говорится об этом, но я думаю, вам было бы лучше загрузить изображения самостоятельно и указать локальные URL-адреса или пути к IKSlideshow. Возможно, стоит сообщить об ошибке (у меня сложилось впечатление, что ImageKit в любом случае довольно глючный). Я думаю, что в документации было бы конкретно указано, поддерживает ли IKSlideshow загрузку изображений из Интернета, тем более что нет никакого пользовательского интерфейса для отображения прогресса загрузки и т.д.

2. В документах действительно говорится, что NSURL работает. Молчание по поводу удаленного или локального. Я должен подчеркнуть, что само sldieshow работает отлично. Загрузка самого себя становится очень запутанной, поскольку IKSlideshow прекрасно перекрывает время загрузки с интервалом слайдов.

3. Повторное рассмотрение, возможно, что slideshowItemAtIndex вызывается в НАЧАЛЕ интервала. Если это так, загрузка самостоятельно будет работать нормально. Я протестирую этот подход завтра и сообщу об этом.

4. ОБНОВЛЕНИЕ: Понедельник, 16 мая 2011: Заменен возврат URL на возврат NSImage (с сохранением количества, равного единице), и поведение точно такое же. При запуске слайд-шоу ввод 10 или около того быстрых стрелок вправо, за которыми следует escape, приводит к сбою. Я убежден, что проблема полностью внутри IKSlideshow, а не в моем приложении. Может быть ошибка в Apple, но я по-прежнему не могу использовать IKSlideshow, поскольку мое приложение направляется в Mac App Store, и я получу плохие отзывы, прежде чем получу возможность попросить пользователей обновить, предполагая, что Apple даже исправит проблему. Теперь я реализую свое собственное слайд-шоу, как я уже сделал для iOS.

5. Возможно, также проблема с потоками? В документах говорится, что методы делегирования могут вызываться в любом потоке, поэтому в случае возврата NSImage вы можете захотеть обернуть его в @synchronized(self) {…}, поскольку NSImage не является потокобезопасным.