为什么标题被重复?

我正在播放当前正在播放的歌曲,并抓取标题和艺术家,并将其存储在parsing中。 由于某些原因,当歌曲播放时,节目增加了4个左右的相同的标题/艺术家。 我只是想要一个。 我该如何解决?

我的对象在parsing数据浏览器中看到

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注意控制台上的时间戳之前进行saveInBackground

如果我是正确的,修复很简单:(a)找出为什么这个方法被调用了很多次,然后修复它,或者(b)在封闭的类中添加一个布尔实例variables,把它busySaving 。 在方法开始的时候,如果busySaving是真的,那么就busySaving出来,否则把它设置为真。 将saveInBackground()更改为saveInBackgroundWithBlock()并重置完成块中的busySaving标志。

编辑现在我们看到为什么它被反复调用:因为通知正在被重复接收。 一种解决方法(想法(a))将停止在getNowPlayingItem开始处观察该通知(NSNotificationCenter removeObserver)。 然后,由于您想要获得后续通知,请使用saveInBackgroundWithBlock在保存后重新添加为观察者。 注意这和saveInBackground不同, 请参阅这里以供参考 。

如果您愿意,上面的想法(b)仍然适用。