Indexpath.row重复导致间歇性索引超出范围错误

时间:2016-10-06 10:48:19

标签: ios swift uitableview

首次加载tableview时,索引print(indexPath.row)显示索引0,1,2。当再次加载tableview时,索引路径重复3次,在调试器中它将是0,1,2,0,1,2,0,1,2。这种情况会在两秒钟内发生,但如果您在此之前滚动表视图,则会出现致命错误:索引超出范围错误。

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

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! EstablishmentCell
    let object = Model.sharedInstance.items[indexPath.row]


    cell.venueDistance.text = object.venueDistance


    cell.titleLabel.text = object.name

    object.loadCoverPhoto { image in
        dispatch_async(dispatch_get_main_queue()) {
            cell.coverPhotoView.image = image
        }
    }


            let myCustomSelectionColorView = UIView()
            myCustomSelectionColorView.backgroundColor = UIColor(red:0.16, green:0.65, blue:0.64, alpha:1.0)
            cell.selectedBackgroundView = myCustomSelectionColorView

        }

}self.activityIndicatorView.stopAnimating()


    return cell

}}

EDIT1: 建立班级

class Establishment: NSObject {


//Properties
var record: CKRecord!
var name: String!
var establishmentDescription: String!
var establishmentOpening: String!

var venueLocation: CLLocation!
weak var database: CKDatabase!
var assetCount = 0
var establishmentDistance: String!
let locationManager = CLLocationManager()


//Map Annotation Properties
//  var coordinate: CLLocationCoordinate2D {
//  return venueLocation.coordinate
//  }

var title: String? {
    return name
}

var venueDescription: String? {
    return establishmentDescription
}

var venueDistance: String? {
    return establishmentDistance
}


//Initializers

init(record: CKRecord, database: CKDatabase) {
    self.record = record
    self.database = database

    //let venueLocation = record["Location"] as? CLLocation



    //let location = CLLocation()


    //let userLocation = CLLocation(latitude: 51.211963, longitude: -0.769298)

    self.name = record["Name"] as? String
    self.establishmentDescription = record["Description"] as? String
    self.establishmentOpening = record["OpeningTimes"] as? String
    self.venueLocation = record["Location"] as? CLLocation



    let location = locationManager.location

    let distanceBetween: CLLocationDistance = (venueLocation!.distanceFromLocation(location!))
    self.establishmentDistance = String(format: "%.f", distanceBetween)


}

func fetchPhotos(completion: (assets: [CKRecord]!) ->()) {
    let predicate = NSPredicate(format: "Establishment == %@", record)
    let query = CKQuery(recordType: "EstablishmentPhoto", predicate: predicate)
    // Intermediate Extension Point - with cursors
    database.performQuery(query, inZoneWithID: nil) { [weak self] results, error in
        defer {
            completion(assets: results)
        }

        guard error == nil,
            let results = results else {
                return
        }

        self?.assetCount = results.count
    }

}



func loadCoverPhoto(completion:(photo: UIImage!) -> ()) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
        var image: UIImage!

        defer {
            completion(photo: image)
        }
        guard let asset = self.record["CoverPhoto"] as? CKAsset,
            path = asset.fileURL.path,
            imageData = NSData(contentsOfFile: path) else {
                return
        }
        image = UIImage(data: imageData)
    }
}

模特课程:

protocol ModelDelegate {
func errorUpdating(error:NSError)
func modelUpdated()   class Model{

//Properties
let EstablishmentType = "Establishment"
static let sharedInstance = Model()
var delegate: ModelDelegate?
var items: [Establishment] = []
let userInfo: UserInfo
let locationManager = CLLocationManager()
var latitude : String!
var longitude : String!
var isLoading = Bool()


//Define Databases

// Represents the default container specified in the iCloud section of the Capabilities tab for the project.

let container: CKContainer
let publicDB: CKDatabase
let privateDB: CKDatabase



//Indicator
// Ask for Authorisation from the User.
func requestLocation() {


    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    self.locationManager.distanceFilter = 10
    self.locationManager.startUpdatingLocation()
    // Check if this app has permission to use location services
    let authorizationStatus:CLAuthorizationStatus = CLLocationManager.authorizationStatus()

    if authorizationStatus == CLAuthorizationStatus.Denied {
        // TODO: Tell user that app functionality may be limited
    }
    else if authorizationStatus == CLAuthorizationStatus.NotDetermined {

        // Manually prompt the user for permission
        self.locationManager.requestWhenInUseAuthorization()
    }
    else if authorizationStatus == CLAuthorizationStatus.AuthorizedWhenInUse {
        self.locationManager.startUpdatingLocation()
    }
}


//Initializers
init () {
    container = CKContainer.defaultContainer()
    publicDB = container.publicCloudDatabase
    privateDB = container.privateCloudDatabase

    userInfo = UserInfo(container: container)
}

@objc  func refresh() {



    let location = locationManager.location
    let radius = CGFloat(1000)


    let predicate = NSPredicate(format: "distanceToLocation:fromLocation:(%K,%@) < %f", "Location", location!, radius)
    let query = CKQuery(recordType: "Establishment", predicate: predicate)


    let sort = CKLocationSortDescriptor(key: "Location", relativeLocation: location!)


    query.sortDescriptors = [sort]

    publicDB.performQuery(query, inZoneWithID: nil) { [unowned self] results, error in



        guard error == nil else {
            dispatch_async(dispatch_get_main_queue()) {

                self.delegate?.errorUpdating(error!)
                print("Cloud Query Error - Refresh: \(error)")
            }
            return
        }
        self.items.removeAll(keepCapacity: true)

        for record in results! {
            let establishment = Establishment(record: record, database: self.publicDB)
            self.items.append(establishment)
        }

        dispatch_async(dispatch_get_main_queue())  {
            self.delegate?.modelUpdated()
        }
    }


}


func establishment(ref: CKReference) -> Establishment! {

    let matching = items.filter { $0.record.recordID == ref.recordID }

    return matching.first

}}

1 个答案:

答案 0 :(得分:0)

提及您的代码中添加的所有数据源方法。

并检查以下方法:

  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
      return Model.sharedInstance.items.count
    }