如何使用Swift关闭打开的文件? [英] How do you close open files using Swift?

查看:199
本文介绍了如何使用Swift关闭打开的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在下载约1300张图像.这些都是小图像,总大小约为500KB.但是,将它们下载并放入userDefault后,出现如下错误:

I am downloading ~1300 images. Those are small images total size is around ~500KB. However, after downloading and putting them into userDefault, I get error as below:

libsystem_network.dylib:nw_route_get_ifindex ::套接字(PF_ROUTE,SOCK_RAW,PF_ROUTE)失败:[24]打开的文件太多

据推测,下载的png图片未关闭.

Assumingely, downloaded png images are not being closed.

我已经通过以下方法扩展了缓存大小:

I already extended cache size via below:

    // Configuring max network request cache size
    let memoryCapacity = 30 * 1024 * 1024 // 30MB
    let diskCapacity = 30 * 1024 * 1024   // 30MB
    let urlCache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "myDiscPath")
    URLCache.shared = urlCache

这是我存储图像的方法:

And this is the approach I got to store images:

    func storeImages (){
        for i in stride(from: 0, to: Cur.count, by: 1) {
            // Saving into userDefault
            saveIconsToDefault(row: i)
        }
    }

将所有这些都添加到userDefault中后,我得到了错误.所以,我知道他们在那里.

I get the error after all of them being added into userDefault. So, I know they are there.

功能:

func getImageFromWeb(_ urlString: String, closure: @escaping (UIImage?) -> ()) {
    guard let url = URL(string: urlString) else {
        return closure(nil)
    }
    let task = URLSession(configuration: .default).dataTask(with: url) { (data, response, error) in
        guard error == nil else {
            print("error: \(String(describing: error))")
            return closure(nil)
        }
        guard response != nil else {
            print("no response")
            return closure(nil)
        }
        guard data != nil else {
            print("no data")
            return closure(nil)
        }
        DispatchQueue.main.async {
            closure(UIImage(data: data!))
        }
    }; task.resume()
}

func getIcon (id: String, completion: @escaping (UIImage) -> Void) {
    var icon = UIImage()

    let imageUrl = "https://files/static/img/\(id).png"

        getImageFromWeb(imageUrl) { (image) in
            if verifyUrl(urlString: imageUrl) == true {
                if let image = image {
                    icon = image
                    completion(icon)
                }
            } else {
                if let image = UIImage(named: "no_image_icon") {
                    icon = image
                    completion(icon)
                }
            }
        }
}

用法:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "CurrencyCell", for: indexPath) as? CurrencyCell else { return UITableViewCell() }

    if currencies.count > 0 {
        let noVal = currencies[indexPath.row].rank ?? "N/A"
        let nameVal = currencies[indexPath.row].name ?? "N/A"
        let priceVal = currencies[indexPath.row].price_usd ?? "N/A"

        getIcon(id: currencies[indexPath.row].id!, completion: { (retImg) in
            cell.configureCell(no: noVal, name: nameVal, price: priceVal, img: retImg)
        })
    }
    return cell
}

推荐答案

URLSession(configuration: .default)语法正在为每个请求创建一个新的URLSession.创建单个URLSession(将其保存在某些属性中),然后将其重新用于所有请求.或者,如果您确实没有对URLSession进行任何自定义配置,则只需使用URLSession.shared:

The URLSession(configuration: .default) syntax is creating a new URLSession for each request. Create a single URLSession (saving it in some property) and then reuse it for all of the requests. Or, if you're really not doing any custom configuration of the URLSession, just use URLSession.shared:

let task = URLSession.shared.dataTask(with: url) { data, response, error in
    ...
}
task.resume()


您提到要在UserDefaults中保存1300张图像.那不是存储此类数据或该数量文件的正确位置.我建议您使用


You mention that you're saving 1300 images in UserDefaults. That's not the right place to store that type of data nor for that quantity of files. I'd suggest you use the "Caches" folder as outlined in the File System Programming Guide: The Library Directory Stores App-Specific Files.

let cacheURL = try! FileManager.default
    .url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    .appendingPathComponent("images")

// create your subdirectory before you try to save files into it
try? FileManager.default.createDirectory(at: cacheURL, withIntermediateDirectories: true)

也不要试图将它们存储在文档"文件夹中.有关更多信息,请参见 iOS存储最佳做法.

Do not be tempted to store them in the "Documents" folder, either. For more information, see iOS Storage Best Practices.

这篇关于如何使用Swift关闭打开的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆