简体   繁体   中英

Indexpath.row repeat lead to intermittent Index out of range error

When tableview is first loaded, the index print(indexPath.row) shows index 0,1,2. When the tableview is loaded again the indexpath repeats itself 3 times, in the debugger it will be 0,1,2,0,1,2,0,1,2. This happens within two seconds, but if you scroll the tableview before this there is a fatal error: Index out of range error.

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: Establishment Class

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)
    }
}

Model Class:

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

}}

Mention all datasource method here which are added in your code .

And also check your following method :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM