0
votes

I'm retrieving set of images from Parse, using the following code using Swift.

var imageResources : Array<UIImage> = []
override func viewDidLoad(){
    super.viewDidLoad()
    self.loadImages()
}

func loadImages(){

    var query = PFQuery(className: "Images")
    query.orderByDescending("objectId")

    query.findObjectsInBackgroundWithBlock ({(objects:[AnyObject]!, error: NSError!) in
        if(error == nil){            

            for object : PFObject! in objects as [PFObject] {                

                var thumbNail = PFFile()
                thumbNail = object["image"] as PFFile
                println("thumNail \(thumbNail)")
                thumbNail.getDataInBackgroundWithBlock({
                   (imageData: NSData!, error: NSError!) in
                   if (error == nil) {
                        let image : UIImage = UIImage(data:imageData)
                        //image object implementation
                        self.imageResources.append(image)
                    }

                })//getDataInBackgroundWithBlock - end

            }//for - end

        }
        else{
            println("Error in retrieving \(error)")
        }

    })//findObjectsInBackgroundWithblock - end


}

My Parse Class detail

class name - Images Parse class schema

When I run this function, it's getting crashed without a message in the console.

Note: I'm able to get the collection of PFFile objects in the callback.

I've replaced "thumbNail.getDataInBackgroundWithBlock({...." block with the synchronous function call thumbNail.getData() like "var imageData= thumbNail.getData() var image = UIImage(data:imageData)"

Then the error says

Warning: A long-running operation is being executed on the main thread. Break on warnBlockingOperationOnMainThread() to debug.

So, I reverted to thumbNail.getDataInBackGroundWithBloack({... But now, there is no error display in the console, as it happens before. Is there anything wrong in my approach please let me know. Any help would be appreciated...!

1
When I try to convert the PFFile to UIImage i.e., (thumbNail.getDataInBackground({.... )that is where the problem occurs, any help on this would be really great. - Suresh Kumar Durairaj
It would be easier to help if you posted the entire stack trace. - Tom Erik Støwer
@TomErikStøwer : In my console there is no stack trace. It just quits the execution abruptly. - Suresh Kumar Durairaj
How many pfobjects are you fetching? - Tom Erik Støwer
I'm fetching 20 PFObjects as the Parse class "Images" having 20 rows. - Suresh Kumar Durairaj

1 Answers

7
votes

I managed to recreate the error, which seems to be some kind of memory leak / zombie on a PFObject. I'm not sure exactly why, but refactoring your code in the following manner got rid of the error in my case:

func loadImages() {

    var query = PFQuery(className: "Images")
    query.orderByDescending("objectId")


    query.findObjectsInBackgroundWithBlock ({(objects:[AnyObject]!, error: NSError!) in
        if(error == nil){

            self.getImageData(objects as [PFObject])

        }
        else{
            println("Error in retrieving \(error)")
        }

    })//findObjectsInBackgroundWithblock - end


}

func getImageData(objects: [PFObject]) {
    for object in objects {

        let thumbNail = object["image"] as PFFile

        println(thumbNail)

        thumbNail.getDataInBackgroundWithBlock({
            (imageData: NSData!, error: NSError!) -> Void in
            if (error == nil) {
                let image = UIImage(data:imageData)
                //image object implementation
                self.imageResources.append(image)
                println(image)
            }

        })//getDataInBackgroundWithBlock - end

    }//for - end
}

EDIT: Incidentally, this also works:

func loadImages() {

    var query = PFQuery(className: "Images")
    query.orderByDescending("objectId")


    query.findObjectsInBackgroundWithBlock ({(objects:[AnyObject]!, error: NSError!) in
        if(error == nil){

            let imageObjects = objects as [PFObject]

            for object in objects {

                let thumbNail = object["image"] as PFFile

                thumbNail.getDataInBackgroundWithBlock({
                    (imageData: NSData!, error: NSError!) -> Void in
                    if (error == nil) {
                        let image = UIImage(data:imageData)
                        //image object implementation
                        self.imageResources.append(image)
                        println(image)
                    }

                })//getDataInBackgroundWithBlock - end

            }//for - end

        }
        else{
            println("Error in retrieving \(error)")
        }

    })//findObjectsInBackgroundWithblock - end


}

This would indicate that the error was due to the following line:

for object : PFObject! in objects as [PFObject] {

Rewriting that line as follows:

for object : PFObject in objects as [PFObject] {

Also removes the error. So the reason for this error seems to be that that you told the program to unwrap something that wasn't an optional.