简体   繁体   中英

Completion closure in swift doesn't appear to be firing

I am following the "Learning Swift" book from O'reilly, and I have some code that looks like:

func deleteDocumentAtURL(url: NSURL) {
    NSLog("Got to top of deleteDocumentAtURL, url: \(url)")
    let fileCoordinator = NSFileCoordinator(filePresenter: nil)
    fileCoordinator.coordinateWritingItemAtURL(url, options: .ForDeleting, error: nil, byAccessor: { (urlForModifying) -> Void in
        NSLog("Here I am")
        do {
            NSLog("Got inside deleteDocumentBlock")
            try NSFileManager.defaultManager().removeItemAtURL(urlForModifying)

            // Remove the URL from the list
            self.availableFiles = self.availableFiles.filter {
                $0 != url
            }

            // Update the collection
            self.collectionView?.reloadData()

        } catch let error as NSError {
            let alert = UIAlertController(title: "Error deleting", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)

            alert.addAction(UIAlertAction(title: "Done", style: .Default, handler: nil))

            self.presentViewController(alert, animated: true, completion: nil)
        }
    })
}

When I run this code, which is triggered by clicking a button in the interface, the application hangs. Also, the log inside the do{} is not firing, which makes me think there's a problem with the whole block? Help appreciated.

Because

let fileCoordinator = NSFileCoordinator(filePresenter: nil)

is local in the function. The variable is already destroyed, if you finished the function. So, the async block can't be executed.

Put fileCoordinator as an instance variable to the class.

You are not handling error and probably have an error

Documentation for coordinateReadingItemAtURL :

outError: On input, a pointer to a pointer for an error object. If a file presenter encounters an error while preparing for this read operation,

that error is returned in this parameter and the block in the reader parameter is not executed.

If you cancel this operation before the reader block is executed, this parameter contains an error object on output.

add error handler and see if you get an error

func deleteDocumentAtURL(url: NSURL) {
    NSLog("Got to top of deleteDocumentAtURL, url: \(url)")
    let fileCoordinator = NSFileCoordinator(filePresenter: nil)
    var error: NSError?
    fileCoordinator.coordinateWritingItemAtURL(url, options: .ForDeleting, error: &error, byAccessor: { (urlForModifying) -> Void in
        NSLog("Here I am")
        do {
            NSLog("Got inside deleteDocumentBlock")
            try NSFileManager.defaultManager().removeItemAtURL(urlForModifying)

            // Remove the URL from the list
            self.availableFiles = self.availableFiles.filter {
                $0 != url
            }

            // Update the collection
            self.collectionView?.reloadData()

        } catch let error as NSError {
            let alert = UIAlertController(title: "Error deleting", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)

            alert.addAction(UIAlertAction(title: "Done", style: .Default, handler: nil))

            self.presentViewController(alert, animated: true, completion: nil)
        }

    })
    //Error:
    if(error != nil){
        print(error)
    }
}

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