У меня есть следующий код для установки курсора из существующего CGImage:
NSPoint hotspot = ...;
CGImageRef cgimg = ...;
if(!cgimg)
return nullptr;
NSImage* nsimg = [[NSImage alloc] initWithCGImage:cgimg size:NSZeroSize];
if(!nsimg)
return nullptr;
NSCursor* pcur = [[NSCursor alloc] initWithImage: nsimg hotSpot: hotspot];
if(!pcur)
return nullptr;
[nsimg release];
// later in the code I set it as current:
[pcur set];
Проблема в том, что он рендерится непоследовательно, иногда выглядит нормально, иногда показывает мусор:
Я использую точно такой же CGImageRef, который отображается нормально, как обычное изображение (тот, что ниже коробки).
Есть идеи, какая проблема может быть?
Фондовые курсоры в том же приложении отображаются нормально. Это на OS X «El Capitan», если это имеет значение.
Отвечая на мой собственный вопрос.
Кажется, что OS X использует некоторый пул автоматического выпуска или тому подобное для хранения промежуточных результатов.
В моей реализации я создаю курсор в одном месте и использую в другом — в ответ на движение мыши. Кажется, что в этом случае OS X пытается использовать память, которая была освобождена.
Для того, чтобы исправить это, я был вынужден использовать [pcur push]; [pcur pop];
последовательность, чтобы убедить OS X немедленно создать курсор:
NSPoint hotspot = ...;
CGImageRef cgimg = ...;
if(!cgimg)
return nullptr;
NSImage* nsimg = [[NSImage alloc] initWithCGImage:cgimg size:NSZeroSize];
if(!nsimg)
return nullptr;
NSCursor* pcur = [[NSCursor alloc] initWithImage: nsimg hotSpot: hotspot];
if(!pcur)
return nullptr;
[nsimg release];
[pcur push]; [pcur pop]; // this is mandatory to force cursor structures to be created.
// store pcur for later use ...
Других решений пока нет …