【问题标题】:Operation is invalid after previous operation上一次操作后操作无效
【发布时间】:2015-04-02 19:21:54
【问题描述】:

我的社交网络应用程序取得了不错的进展。我遇到了一个问题。我有一个 ViewController,它提供了一个 TableView,它填充了我的解析数据库中的内容。在单元格中,我有一个 RSVP 按钮,该按钮应该在单击时根据 indexPath 向数据库发送 RSVP,并在再次单击时将其删除。我相信我的逻辑是正确的,但是,我不断收到错误:

上一次操作后操作无效。

我放置了一个断点来定位崩溃的原因,并且我发现它发生在 rsvpButtonClicked IBOutlet 函数中的 addUniqueObject 行。

有人可以帮助我吗?我的代码如下。

import UIKit
import CoreLocation

class MainFeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var eventsTable: UITableView!

var user = PFUser.currentUser()
var refresher: UIRefreshControl!

var eventId = [String]()
var eventNames = [String]()
var eventCity = [String]()
var imageFiles = [PFFile]()
var getEventsQuery = 0
var userRsvps = [NSArray]()
var rsvp = 0

override func viewDidLoad() {
    super.viewDidLoad()
    getuserlocation()
    getTodayDate()
}

override func viewWillAppear(animated: Bool) {
    refreshControl()
    //getMyRsvps()
}

override func viewDidAppear(animated: Bool) {
    let timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "eventQuery", userInfo: nil, repeats: false)
}


func getMyRsvps() {
    var getRsvps = PFUser.query()
    getRsvps.whereKey("objectId", equalTo: user.objectId)
    getRsvps.whereKeyExists("myrsvp")
    getRsvps.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            self.userRsvps.append(objects)
        }
    }
}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = self.eventsTable.dequeueReusableCellWithIdentifier("mainFeedContent") as MainFeedContentTableViewCell

    cell.eventName.text = eventNames[indexPath.row]
    imageFiles[indexPath.row].getDataInBackgroundWithBlock{
        (imageData: NSData!, error: NSError!) -> Void in
        if error == nil {
            let image = UIImage(data: imageData)
            cell.eventImage.image = image
        }
    }

    cell.rsvpButton.tag = indexPath.row
    cell.rsvpButton.addTarget(self, action: "rsvpButtonClick:", forControlEvents: UIControlEvents.TouchUpInside)

    return cell
}

@IBAction func rsvpButtonClick(sender: UIButton) {
    var senderButton = sender
    println("Current row \(senderButton.tag)")

    var tempObject = eventId[senderButton.tag]
    println("\(tempObject)")

    PFUser.currentUser().addUniqueObject(tempObject, forKey: "myrsvp")
    PFUser.currentUser().saveInBackground()

}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return eventId.count
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let mainViewIdentifier = "showDetail"
    if segue.identifier == mainViewIdentifier {
        if let destination = segue.destinationViewController as? DetailViewController {
            if let feedIndex = eventsTable.indexPathForSelectedRow()?.row {
                destination.eventNames = eventNames[feedIndex]
                destination.eventId = eventId[feedIndex]
                destination.eventImagesFile = imageFiles[feedIndex]
            }
        }
    }
}

func eventQuery() {
    let getEventsQuery = PFQuery(className: "Events")
    getEventsQuery.whereKey("eventLocation", nearGeoPoint: user["location"] as PFGeoPoint, withinMiles: user["preferredDistanceEvents"] as Double)
    getEventsQuery.limit = 16
    getEventsQuery.findObjectsInBackgroundWithBlock {(objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            println("Successfully retrieved \(objects.count) events")
            for object in objects {
                self.eventId.append(object.objectId)
                self.eventNames.append(object["eventName"] as String)
                self.eventCity.append(object["eventCity"] as String)
                self.imageFiles.append(object["eventPicture"] as PFFile)
                self.eventsTable.reloadData()
            }
        } else {
            println(error)
        }
    }
}

func refreshControl() {

    refresher = UIRefreshControl()
    refresher.attributedTitle = NSAttributedString(string: "Pull to refresh")
    refresher.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged)
    self.eventsTable.addSubview(refresher)

}

/*
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {

    var height: CGFloat = scrollView.frame.size.height
    var contentYoffset: CGFloat = scrollView.contentOffset.y
    var distanceFromBottom: CGFloat = scrollView.contentSize.height - contentYoffset
    if distanceFromBottom <= height {
        println("End of Table")
        refresh()
    }
}
*/

func refresh() {
    self.getEventsQuery++
    if self.getEventsQuery < self.eventId.count {
        let refreshEventsQuery = PFQuery(className: "Events")
        refreshEventsQuery.whereKey("location", nearGeoPoint: user["location"] as PFGeoPoint, withinMiles: user["preferredDistanceEvents"] as Double)
        refreshEventsQuery.whereKey("objectId", notContainedIn: eventId)
        refreshEventsQuery.limit = 4
        refreshEventsQuery.findObjectsInBackgroundWithBlock {(objects: [AnyObject]!, error: NSError!) -> Void in
            if error == nil {
                println("Successfully retrieved \(objects.count) events")
                for object in objects {
                    self.eventNames.append(object["eventName"] as String)
                    self.eventCity.append(object["City"] as String)
                    self.imageFiles.append(object["eventPicture"] as PFFile)
                    self.eventId.append(object.objectId)
                    self.eventsTable.reloadData()
                }
            } else {
                println(error)
            }
        }
    } else {
        println("No More Events. Sorry")
    }
    self.refresher.endRefreshing()
}

func getuserlocation() {
    PFGeoPoint.geoPointForCurrentLocationInBackground { (geopoint: PFGeoPoint!, error: NSError!) -> Void in
        if error == nil {
            self.user["location"] = geopoint
            self.user.saveInBackground()
        }
    }
}

func getTodayDate(){
    var today = NSDate()
    var calendar = NSCalendar.currentCalendar()
    var flags = NSCalendarUnit.HourCalendarUnit | NSCalendarUnit.MinuteCalendarUnit
    var components = calendar.components(flags, fromDate: today)
    var hour = components.hour
    var minutes = components.minute

    println("Today is \(today). The time is \(hour):\(minutes)")
}

}

【问题讨论】:

  • myrsvp是什么服务器上的型号?指针?数组?关系?
  • 这是我解析数据库中的数组类型。
  • myrsvp 本质上是一个数组,包含用户 rsvp'd 到的事件的所有事件 ID。
  • 你有没有在currentUser上给fetch:打电话?
  • 不,我不会在 currentUser 上调用 fetch。我有用户登录并创建一个新的 currentUser 会话。

标签: ios swift parse-platform


【解决方案1】:

我认为这是解析中的错误(在与 JS 共享的代码中,因为我在那里遇到了问题)。具体来说,当混合使用 add 和 remove PFObject 方法来操作数组列时,会出现此故障。

我已成功使用以下两种解决方法:

  1. 分隔添加和删除,中间保存。换句话说,构建您自己的addToColAndSaveremoveFromColAndSave 便捷方法。如果您已呼叫其中一个,请在保存完成之前不要呼叫另一个。
  2. 可能更简单:重构代码以避免数组上的添加/删除方法。相反,使用getter(JS 中的get,iOS 中的objectForKey:)来获取内存中的数组,然后本机操作它。使用 sdk setter 更新对象。

【讨论】:

  • 有趣的方法。两个都试试!
猜你喜欢
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
相关资源
最近更新 更多