NSPasteboard и простые пользовательские данные - PullRequest
16 голосов
/ 30 августа 2011

Мне очень тяжело пытаться заставить работать NSPasteboard, так что прости меня за отсутствие понимания.

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

Я попытался изучить NSPasteboardItemDataProvider, NSPasteboardItem и NSData, но все они запуталисьделать что-то так просто.На самом деле, я понятия не имею, как правильно сделать что-то настолько простое - каждый пример, похоже, имеет дело со строковым типом или чем-то намного более сложным.Селектор [NSMutable SetData], похоже, тоже не существует, хотя в коде нет предупреждений.

Если кто-то может указать мне правильное направление, я был бы очень благодарен.:)

Редактировать: я использую [dragImage ...], чтобы помочь мне с операциями перетаскивания.

1 Ответ

43 голосов
/ 30 августа 2011

Существует два способа использования NSPasteboard.

Старый способ: прикрепить данные к плате самостоятельно

Сначала вы должны объявить типы, которые вы положите на монтажный картон.Вы также назначаете объект, который будет «владеть» монтажным столом, а это означает, что это объект, помещающий материал в монтажный картон.

Следующим шагом является размещение данных на монтажном столе.Этот шаг не является обязательным.

«Необязательно ?!», спросите вы.Да: если вы не помещаете данные в монтажный картон для любого типа, который вы объявили, и для этого впоследствии необходимы эти данные (для вставки / удаления), тогда монтажный щит попросит вас (владельца) об этом .Это называется обещать эти данные, и это хорошо, когда эти данные дорого копировать (большие) или генерировать.

Есть пять способов поместить вещи в монтажный картон (кроме того, чтобы их попросили):

  • В виде строки. Подходит только для простого текста.Монтажный стол будет обрабатывать преобразование его в различные кодировки по мере необходимости.
  • Как список свойств. Хорошо только для списков свойств (и да, это принудительно применяется до конца, поэтому массивизображения не считаются), или вещи, которые вы можете конвертировать в и из списков свойств.Это может включать ваши собственные объекты, если вы реализуете их в них.
  • в качестве необработанных данных. Подходит для существующих типов данных, таких как типы изображений (PNG, JPEG и т. Д.) И AТипы / V (MPEG-4 и т. Д.).
  • Как содержимое файла, идентифицируемого путем. Хорошо, только если то, что вы перетаскиваете / копируете, уже является файлом.
  • Как содержимое файловой оболочки. Если вы еще не используете файловые оболочки, можете смело игнорировать это.

Более новый способ: закреплять объектына доску, и пусть они превращаются в данные

Новая особенность, введенная в Snow Leopard, заключается в том, чтобы ваши объекты могли сами записывать себя в монтажный картон.Для этого требуется, чтобы они знали все о себе, что вы захотите на монтажном столе, включая идентификаторы.

Вы должны привести свои объекты в соответствие NSPasteboardWriting и NSPasteboardReading .

Протокол записи будет выглядеть очень знакомо теперь, когда вы знаете старый способ.Монтажная панель спрашивает ваш объект , какие типы он будет представлять как , затем запрашивает объект списка свойств для каждого типа .(Протокол также предоставляет способ обещать типы вместо того, чтобы данные для них запрашивались немедленно.)

Чтобы скопировать объекты, соответствующие NSPasteboardWriting, в монтажный картон, отправьте монтажному документу сообщение clearContents (требуется вновый способ, необязательный по старому), затем writeObjects:, передающий массив объектов, которые вы хотите скопировать.

Протокол чтения, как и следовало ожидать, является обратным.Для вставки вы отправляете в картон a readObjectsForClasses:options: сообщение .Монтажный стол спрашивает каждый из этих классов , какие типы он распознает , затем (необязательно) пытается создать один или несколько экземпляров из того, что находится на монтажном столе .

.Недостатком этого, особенно в том, что касается повторного использования идентификаторов, является то, что это может в конечном итоге нарушить отделение уровня вашей модели от уровня контроллера. Инициализатору чтения необходимо знать, что делать с идентификатором, если вы хотите, чтобы он возвращал существующий объект, имеющий этот идентификатор.Это означает, что ему нужно либо поговорить с контроллером (плохо), либо продублировать код поиска контроллера (хуже).

Я не знаю хорошего способа реализации move drag-and-отделение (включая, помимо прочего, переупорядочение) с новыми протоколами, не сталкиваясь с этой проблемой.Для перетаскивания копий (включая, помимо прочего, кросс-процессинг) это нормально, поскольку для этого вам не нужны идентификаторы - просто сгенерируйте данные на одном конце и создайте из них новую копию на другом.

Преимущество нового способа заключается в том, что обработка нескольких предметов намного более вменяема. По-старому, есть только один «элемент» - на самом деле, вообще никакого понятия об элементах - в нескольких типах. Если вы хотели скопировать или перетащить несколько объектов, вы создали массив и скопировали его как единый список свойств для некоторого типа, а затем заново создали / извлекли несколько элементов из этого единого списка свойств на другом конце. Более новый способ явно поддерживает один или несколько элементов; при копировании нескольких вещей вы просто передаете их всем writeObjects:.

Ваш случай: один идентификатор NSUInteger

Поместите его в NSNumber (который является списком свойств) и используйте его по-старому.

...