不寻常的核心数据行为 - 保存另一个对象效果吗?

时间:2015-10-17 00:24:29

标签: macos swift core-data

所以我正在努力学习Swift,我确信我做错了什么,但我无法弄清楚那可能是什么。

我正在编写一个笔记应用程序,以帮助自己熟悉该语言。它具有表视图(由NSArrayController填充)。单击表视图中的注释会弹出一个视图控制器,显示注释的标题和正文。单击“添加”按钮可创建新的笔记管理对象,并将其传递给与用于编辑的视图控制器相同的视图控制器。

编辑注释时,选择某些文本并按下命令-l的用户可以创建一个标题等于所选文本的新注释。

除命令-l外,一切都很好。这种行为是最不寻常的,我敢肯定,这是我造成的。

它是这样的:

  1. 创建一个注释并填写标题和正文。让我们说它被称为'第一',身体是'这是第一个,而不是第二个。'
  2. 选择一些文本('second')并按下命令-l。这将保存当前注释,创建新的托管对象,填写标题(“秒”),并在视图控制器中显示。输入正文('这是第二个')
  3. 保存说明。
  4. 视图控制器现在列出了两个音符。单击第一个音符('first')现在显示第二个音符的说明。 ('这是第二个')
  5. 以下是一些代码:

    从主(表视图)控制器:

    override func prepareForSegue(segue: NSStoryboardSegue, sender: AnyObject?) {
        if segue.identifier=="CreateNote" {
            let nextViewController = segue.destinationController as! DetailViewController
            nextViewController.managedContext=self.managedContext
            nextViewController.note = NSEntityDescription.insertNewObjectForEntityForName("Note", inManagedObjectContext: managedContext!) as! Note
        }
        else if segue.identifier=="EditNote" {
            let theSelection = tableView.selectedRow
            let theNote = noteArrayController?.arrangedObjects[theSelection] as! Note
            let nextViewController = segue.destinationController as! DetailViewController
            nextViewController.managedContext=self.managedContext
            nextViewController.note = theNote
        }
    }
    

    从详细视图控制器:

    import AppKit
    
    class DetailViewController: NSViewController, KeyNotificationProtocol {
    
        @IBOutlet weak var noteTitle: NSTextField!
        @IBOutlet var noteBody: TWTextView!
    
        @IBAction func backButton(sender: AnyObject) {
            saveNote()
            if historyStack.isNotEmpty() {
                note=findNoteByName(historyStack.pop())
                loadNote()
            }
        }
    
        @IBAction func dismissButton(sender: AnyObject) {
            saveNote()
            self.dismissController(self)
        }
        var managedContext: NSManagedObjectContext?
        var note: Note?
        var noteNameToLoad: String?
        var historyStack = Stack<String>()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            loadNote()
            noteBody.keyDelegate = self
    
            var requestArray: [KeyRequest] = []
    
            requestArray.append(KeyRequest(theFlags: [NSEventModifierFlags.CommandKeyMask],
                theKey: "l",
                theTag: "link",
                theFunc: self.createLink))
    
            noteBody.keysOfInterest=requestArray
        }
    
        override func viewWillDisappear() {
            saveNote()
        }
    
        func keypressWasReceived(keypress: KeyNotificationData) {
            keypress.keypressRequest.funcToCall()
        }
    
        func createLink() {
            print("create link!")
            if(noteBody.selectedRange().length>0) {
                saveNote()
                if let swRange = noteBody.string?.rangeFromNSRange(noteBody.selectedRange()) {
                    let selectedText = noteBody.string!.substringWithRange(swRange)
                    let tempNote=findNoteByName(selectedText)
                    if(tempNote==nil) {
                        historyStack.push((note?.title)!)
                        self.note = (NSEntityDescription.insertNewObjectForEntityForName("Note", inManagedObjectContext: managedContext!) as! Note)
                        self.note!.title=selectedText
                        self.note!.attributedBody=NSAttributedString(string: "New note")
                        loadNote()
                    }
                    else {
                        print("note exists")
                    }
                }
    
            }
        }
    
        func saveNote() -> BooleanType {
            if (managedContext?.hasChanges != nil) {
                self.note?.title=noteTitle.stringValue
                self.note?.attributedBody=noteBody.textStorage
                var saved = false
    
                do {
                    try managedContext?.save()
                    saved = true
                }
                catch let error as NSError {
                    print("Error saving \(error)", terminator: "")
                }
    
                return saved
            }
            else {
                return true
            }
    
        }
    
        func loadNote() {
            if self.note?.title==nil {
                self.note?.title=""
            }
            noteTitle.stringValue = (self.note?.title)!
    
            if(self.note?.attributedBody?.length>0) {
                noteBody.textStorage?.setAttributedString((self.note?.attributedBody)!)
            }
            else if(self.note?.body?.characters.count>0) {
                noteBody.textStorage?.setAttributedString(NSAttributedString(string: (self.note?.body)!))
            }
            else {
                noteBody.textStorage?.setAttributedString(NSAttributedString(string: ""))
            }
    
        }
    
        func findNoteByName(noteName: String) -> Note? {
            let freq = NSFetchRequest(entityName: "Note")
            freq.predicate = NSPredicate(format: "title == %@", noteName)
            var result: [Note]=[]
            do {
                result = try managedContext?.executeFetchRequest(freq) as! [Note]
            }
            catch let theError as NSError {
                print(theError)
                result=[]
            }
    
            if result.count>0 {
                return result[0]
            }
            else {
                return nil
            }
        }    
    }
    

    创建第一个音符:

    enter image description here

    按下command-l后,将保存第一个音符并创建第二个音符:

    enter image description here

    保存第二个音符(单击完成后),返回到表格视图,然后单击第一个音符:

    enter image description here

    因此,为了找出问题所在,我为managedObjectContext通知添加了KVO。我在appdelegate中完成了所有核心数据设置:

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "shitHappened:", name: NSManagedObjectContextObjectsDidChangeNotification, object: managedObjectContext)
    
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "shitHappened:", name: NSManagedObjectContextDidSaveNotification, object: managedObjectContext)
    
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "shitHappened:", name: NSManagedObjectContextWillSaveNotification, object: managedObjectContext)
    }
    
    func shitHappened(sender: AnyObject) {
        print("-- something happened with core data --")
        print(sender)
    }
    

    监视观察者生成的输出,我看不到正在更新的第一个音符&amp;保存,使身体设置为第二个!这是来自那里的数据。在此日志数据的最后,有一条通知说First Note已被修改。哪里?!

    -- something happened with core data --
    NSConcreteNotification 0x608000045c10 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        inserted = "{(\n    <testwiki.Note: 0x6100000a8fa0> (entity: Note; id: 0x610000020b40 <x-coredata:///Note/tBCC61422-BDB8-44EB-A1A0-D32126C892354> ; data: {\n    attributedBody = nil;\n    body = nil;\n    title = \"\";\n})\n)}";
        managedObjectContext = "<NSManagedObjectContext: 0x6180001c01e0>";
    }}
    create link!
    -- something happened with core data --
    NSConcreteNotification 0x61000005af40 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        managedObjectContext = "<NSManagedObjectContext: 0x6180001c01e0>";
        updated = "{(\n    <testwiki.Note: 0x6100000a8fa0> (entity: Note; id: 0x610000020b40 <x-coredata:///Note/tBCC61422-BDB8-44EB-A1A0-D32126C892354> ; data: {\n    attributedBody = \"This is the first, not the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = \"The First Note\";\n})\n)}";
    }}
    -- something happened with core data --
    NSConcreteNotification 0x61000004dc50 {name = NSManagingContextWillSaveChangesNotification; object = <NSManagedObjectContext: 0x6180001c01e0>}
    -- something happened with core data --
    NSConcreteNotification 0x61000024c870 {name = NSManagingContextDidSaveChangesNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        inserted = "{(\n    <testwiki.Note: 0x6100000a8fa0> (entity: Note; id: 0x610000228e00 <x-coredata://18C6EA07-F369-4289-B333-53326C2B9DFE/Note/p226> ; data: {\n    attributedBody = \"This is the first, not the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = \"The First Note\";\n})\n)}";
        updated = "{(\n)}";
    }}
    loadNote
    Optional("second")
    Optional(New note{
    })
    -- something happened with core data --
    NSConcreteNotification 0x610000053a10 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        inserted = "{(\n    <testwiki.Note: 0x6100000a9a80> (entity: Note; id: 0x6100002298c0 <x-coredata:///Note/tBCC61422-BDB8-44EB-A1A0-D32126C892355> ; data: {\n    attributedBody = \"New note{\\n}\";\n    body = nil;\n    title = second;\n})\n)}";
        managedObjectContext = "<NSManagedObjectContext: 0x6180001c01e0>";
    }}
    -- something happened with core data --
    NSConcreteNotification 0x61800005cbc0 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        managedObjectContext = "<NSManagedObjectContext: 0x6180001c01e0>";
        updated = "{(\n    <testwiki.Note: 0x6100000a9a80> (entity: Note; id: 0x6100002298c0 <x-coredata:///Note/tBCC61422-BDB8-44EB-A1A0-D32126C892355> ; data: {\n    attributedBody = \"This is the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = second;\n})\n)}";
    }}
    -- something happened with core data --
    NSConcreteNotification 0x618000240d50 {name = NSManagingContextWillSaveChangesNotification; object = <NSManagedObjectContext: 0x6180001c01e0>}
    -- something happened with core data --
    NSConcreteNotification 0x61800005d970 {name = NSManagingContextDidSaveChangesNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        inserted = "{(\n    <testwiki.Note: 0x6100000a9a80> (entity: Note; id: 0x61800003ac20 <x-coredata://18C6EA07-F369-4289-B333-53326C2B9DFE/Note/p227> ; data: {\n    attributedBody = \"This is the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = second;\n})\n)}";
        updated = "{(\n)}";
    }}
    -- something happened with core data --
    NSConcreteNotification 0x618000242310 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        managedObjectContext = "<NSManagedObjectContext: 0x6180001c01e0>";
        updated = "{(\n    <testwiki.Note: 0x6100000a9a80> (entity: Note; id: 0x61800003ac20 <x-coredata://18C6EA07-F369-4289-B333-53326C2B9DFE/Note/p227> ; data: {\n    attributedBody = \"This is the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = second;\n})\n)}";
    }}
    -- something happened with core data --
    NSConcreteNotification 0x618000242f40 {name = NSManagingContextWillSaveChangesNotification; object = <NSManagedObjectContext: 0x6180001c01e0>}
    -- something happened with core data --
    NSConcreteNotification 0x608000046240 {name = NSManagingContextDidSaveChangesNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        inserted = "{(\n)}";
        updated = "{(\n    <testwiki.Note: 0x6100000a9a80> (entity: Note; id: 0x61800003ac20 <x-coredata://18C6EA07-F369-4289-B333-53326C2B9DFE/Note/p227> ; data: {\n    attributedBody = \"This is the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = second;\n})\n)}";
    }}
    about to segue to editNote
    with title
    Optional("The First Note")
    Optional(This is the second.{
        NSFont = "\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\"";
        NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0";
    })
    ------------------------
    loadNote
    Optional("The First Note")
    Optional(This is the second.{
        NSFont = "\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\"";
        NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0";
    })
    -- something happened with core data --
    NSConcreteNotification 0x618000241aa0 {name = NSObjectsChangedInManagingContextNotification; object = <NSManagedObjectContext: 0x6180001c01e0>; userInfo = {
        managedObjectContext = "<NSManagedObjectContext: 0x6180001c01e0>";
        updated = "{(\n    <testwiki.Note: 0x6100000a8fa0> (entity: Note; id: 0x610000228e00 <x-coredata://18C6EA07-F369-4289-B333-53326C2B9DFE/Note/p226> ; data: {\n    attributedBody = \"This is the second.{\\n    NSFont = \\\"\\\\\\\"Helvetica 12.00 pt. P [] (0x610000247e90) fobj=0x101b11ca0, spc=3.33\\\\\\\"\\\";\\n    NSParagraphStyle = \\\"Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\\\\n    28L,\\\\n    56L,\\\\n    84L,\\\\n    112L,\\\\n    140L,\\\\n    168L,\\\\n    196L,\\\\n    224L,\\\\n    252L,\\\\n    280L,\\\\n    308L,\\\\n    336L\\\\n), DefaultTabInterval 0, Blocks (\\\\n), Lists (\\\\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0\\\";\\n}\";\n    body = nil;\n    title = \"The First Note\";\n})\n)}";
    }}
    

    其他说明:我正在使用重写的keyDown函数在子类NSTextView中查看命令-l。

    编辑:我忽略了指出如果我创建了一长串音符,使用命令-l从一个音符到另一个音符,当我回去看看时,该链中的每个音符都会有相同的音符。它们。

1 个答案:

答案 0 :(得分:0)

所有attributesBodies指向相同的textStorage。

更改

Toolbar

self.note?.attributedBody=noteBody.textStorage