我正在获取当前播放的歌曲,并捕获标题和艺术家,并将其存储在解析中。由于某种原因,当歌曲播放时,程序会添加4个左右的相同标题/艺术家。我只想要一个。我该如何解决?

my objects as seen in the parse data browser

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated);

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "getNowPlayingItem", name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification, object: nil)
    musicPlayer.beginGeneratingPlaybackNotifications()
}

func getNowPlayingItem() {

    NSNotificationCenter.defaultCenter().removeObserver(self)

    if  let nowPlaying = musicPlayer.nowPlayingItem  {
        let title = nowPlaying[MPMediaItemPropertyTitle] as? String
        let artisttest = nowPlaying[MPMediaItemPropertyTitle]
        if let artist = nowPlaying[MPMediaItemPropertyArtist] as? String{
            let objectPointer = PFObject(className: "Pointer")
            let object = PFObject(className: "MasterSongs")

            let query = PFQuery(className: "Pointer")
            query.findObjectsInBackgroundWithBlock({
                (objects: [AnyObject]?, error: NSError?) -> Void in
                var objectIDs = objects as! [PFObject]

                for i in 0...objectIDs.count-1{
                    self.Parsearray.append((objectIDs[i].valueForKey("title") as? String)!)
                    // print(self.Parsearray)
                }

                if self.Parsearray.contains(title!){
                    print("already in db")
                }else{
                    objectPointer["title"] = title
                    objectPointer["user"] = PFUser.currentUser()
                    objectPointer["artist"] = artist

                    objectPointer.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in
                        if(error != nil){
                            print(error)
                        }else{
                            NSNotificationCenter.defaultCenter().addObserver(self, selector: "getNowPlayingItem", name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification, object: nil)
                        }
                    })
                }
            })
        }else{

            let objectPointer = PFObject(className: "Pointer")

            let query = PFQuery(className: "Pointer")
            query.findObjectsInBackgroundWithBlock({
                (objects: [AnyObject]?, error: NSError?) -> Void in
                var objectIDs = objects as! [PFObject]

                for i in 0...objectIDs.count-1{
                    self.Parsearray.append((objectIDs[i].valueForKey("title") as? String)!)

                    // print(self.Parsearray)
                }

                if self.Parsearray.contains(title!){
                    print("already in db")
                }else{
                    objectPointer["title"] = title
                    objectPointer["user"] = PFUser.currentUser()
                    objectPointer["artist"] = "No artist found :("

                    objectPointer.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in

                        if(error != nil){
                            print(error)
                        }else{
                            NSNotificationCenter.defaultCenter().addObserver(self, selector: "getNowPlayingItem", name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification, object: nil)
                        }
                    })
                }
            })
        }
    }
}

最佳答案

根据证据,很有可能快速调用了函数getNowPlayingItem几次。它启动查询,少数查询在保存任何内容之前就已完成。这些查询完成(尚未完成保存)将启动少量保存,您将获得少量对象。

通过在方法开始时和saveInBackground注意控制台上的时间戳记之前打印一条消息来检查此情况。

如果我是对的,则修复很简单:(a)找出为什么多次调用该方法并进行修复,或者(b)向该封闭类添加一个布尔实例变量,将其命名为busySaving 。在方法开始时,如果busySaving为true,则请保释,否则将其设置为true。将您的saveInBackground()更改为saveInBackgroundWithBlock()并在完成块中重置busySaving标志。

编辑
现在我们了解为什么要重复调用它:因为通知是重复接收的。一种解决方法(上述想法(a))是在getNowPlayingItem开始时停止观察该通知(NSNotificationCenter removeObserver)。然后,由于要获取后续通知,请在保存后使用saveInBackgroundWithBlock将自己重新添加为观察者。请注意,这与saveInBackground see here for reference不同。

如果您愿意,上述想法(b)也同样适用。

10-08 05:54