【问题标题】:Is NSFileManager.removeItemAtPath asynchronous?NSFileManager.removeItemAtPath 是异步的吗?
【发布时间】:2017-02-19 16:55:52
【问题描述】:

文档中没有任何内容,似乎该方法应该是同步的,它甚至返回一个成功值。 我有一个带有一些单元格的 UITableView,用户可以删除与这些单元格关联的项目。这会调用以下代码:

if(manager.fileExistsAtPath(vidUrl.path!))
{
    do
    {
        try manager.removeItemAtURL(vidUrl)
    }
    catch 
    {
        NSLog("failed to delete video at path \(vidUrl)")
    }
}
// reload the table data here

但每次调用此文件时,重新加载表数据时文件仍然存在。我看不到任何将完成块传递给文件管理器以在文件删除时执行的方法。 NSFileManager 委托只有“should”方法,没有“did”方法。

我最终在 catch 语句之后添加了这些非常老套的行,但肯定有更好的方法来处理这个问题吗?

while(manager.fileExistsAtPath(vidUrl.path!))
{
    usleep(5000)
}

编辑 下面的完整代码(由 UIAlertAction 触发)

let okAction = UIAlertAction(title: ok, style: UIAlertActionStyle.Destructive, handler:{
    (action: UIAlertAction) -> Void in
    HUD.show(HUDContentType.LabeledProgress(title: deleteString, subtitle: "Deleting..."))
    for item in self.selectedVideos
    {
        let vidUrl = (item as! VideoItem).filePath
        if(manager.fileExistsAtPath(vidUrl.path!))
        {
            do
            {
                try manager.removeItemAtURL(vidUrl)
                // If I remove this while loop then files still exist in the loadVideos below
                while(manager.fileExistsAtPath(vidUrl.path!))
                {
                    usleep(5000)
                }
            }
            catch {NSLog("failed to delete video at path \(vidUrl)")}
        }
    }
    self.loadVideos()
    HUD.hide()
})

和 loadVideos 函数

func loadVideos()
{
    self.videos.removeAll()
    let documentsUrl = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
    do {
        let width = self.collectionView!.bounds.width * 0.4
        let targetSize = CGSizeMake(width,width)
        let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( documentsUrl, includingPropertiesForKeys: nil, options: [])
        let vidFiles = directoryContents.filter{ $0.pathExtension == VIDEO_EXTENSION }
        let validUrls = NSMutableArray()
        for vid in vidFiles
        {
            let thumbDuration = GalleryThumbLoader.getVideoThumb(vid.absoluteURL, size: targetSize)
            let video = VideoItem(filePath: vid.absoluteURL, bitmap: thumbDuration.bitmap, duration: thumbDuration.duration)
            videos.append(video)
            dispatch_async(dispatch_get_main_queue(),
            {
                self.collectionView!.reloadData()
            })
            validUrls.addObject(vid.absoluteURL.path!)
        }
    } catch let error as NSError {
        NSLog(error.localizedDescription)
        videos = [VideoItem]()
    }
    NSLog("finished loading videos")
}

【问题讨论】:

  • 你能贴出完整的代码吗?
  • reloadData() 在重复循环中非常昂贵。放在重复循环之后。
  • 好的,但这与报告的问题无关。问题是 vidFiles 包含我刚刚删除的文件,如果我不睡觉的话
  • 为什么不直接从self.videos 中删除项目?这比检索整个目录便宜吗? validUrls 是干什么用的?其实没用过。
  • 我怀疑它也是异步的,我的单元测试被认为是同步的假设搞砸了。你找到任何官方的答案或确认了吗?

标签: ios swift uitableview nsfilemanager synchronous


【解决方案1】:

你在子线程上做!

你会在处理文件之前判断它。像这样: [NSThread isMainThread];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2015-08-03
    • 2019-01-05
    • 2021-03-30
    • 2019-01-13
    • 1970-01-01
    相关资源
    最近更新 更多