UndoManager в подклассе NSResponder (macOS) - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь реализовать отмену / повтор в моей модели.Поэтому я сделал свой класс модели подклассом NSResponder, а затем реализовал следующее:

note : этот код редактируется на основе дополнительных исследований после комментариев

func setAnnotations(_ newAnnotations: [Annotation]) {
    let currentAnnotations = self.annotations

    self.undoManager.registerUndo(withTarget: self, handler: { (selfTarget) in
        selfTarget.setAnnotations(currentAnnotations)
    })

    self.annotations = newAnnotations
}

Annotation является структурой.

Код внутри замыкания никогда не выполняется.Изначально я заметил, что undoManager - это nil, но затем я нашел этот фрагмент:

private let _undoManager = UndoManager()
override var undoManager: UndoManager {
   return _undoManager
}

Теперь undoManager больше не равен нулю, но код внутри замыкания все еще не выполняется.

Что мне здесь не хватает?

1 Ответ

1 голос
/ 10 мая 2019

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

import Cocoa
class MyResponder : NSResponder {
    private let _undoManager = UndoManager()
    override var undoManager: UndoManager {
        return _undoManager
    }
    typealias Annotation = String
    var annotations = ["hello"]
    func setAnnotations(_ newAnnotations: [Annotation]) {
        let currentAnnotations = self.annotations
        self.undoManager.registerUndo(withTarget: self, handler: { (selfTarget) in
            selfTarget.setAnnotations(currentAnnotations)
        })
        self.annotations = newAnnotations
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    let myResponder = MyResponder()
    @IBOutlet weak var window: NSWindow!
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print(self.myResponder.annotations)
        self.myResponder.setAnnotations(["howdy"])
        print(self.myResponder.annotations)
        self.myResponder.undoManager.undo()
        print(self.myResponder.annotations)
    }
}

Вывод:

["hello"]
["howdy"]
["hello"]

Так что Undo работает отлично. Если это не происходит для вас, возможно, вы каким-то образом неправильно управляете своим «классом моделей».


Кстати, правильнее написать закрытие регистрации так:

    self.undoManager.registerUndo(withTarget: self, handler: {
        [currentAnnotations = self.annotations] (selfTarget) in
        selfTarget.setAnnotations(currentAnnotations)
    })

Это гарантирует, что self.annotations не будет захвачено преждевременно.

...