尝试在UserDefaults中设置数据时,应用程序冻结,未给出错误

时间:2019-03-29 10:21:21

标签: ios swift nsuserdefaults codable

我想将一组自定义对象保存到UserDefaults。在大多数情况下,它运行良好,但有时执行会冻结在步骤2上,并在几秒钟后继续执行,我将数据对象保存到UserDefaults。它不是定期发生,但是当数组包含许多元素时,似乎更经常发生此问题。

从未抛出任何错误,似乎编码或保存Data在某种程度上已损坏,但我不明白这里可能是什么问题。

我的自定义对象类:

struct AWFavourite: Codable {

    enum MediaType: String, Codable {
        case album
        case artist
        case playlist
    }

    let identifier: String
    let title: String
    let mediaType: MediaType
    let image: UIImage?
    let source: AWMediaSource

    enum CodingKeys: String, CodingKey {
        case identifier
        case title
        case mediaType
        case image
        case source
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let imageData = try container.decode(Data.self, forKey: .image)
        image = NSKeyedUnarchiver.unarchiveObject(with: imageData) as? UIImage 

        title = try container.decode(String.self, forKey: .title)
        identifier = try container.decode(String.self, forKey: .identifier)
        mediaType = try container.decode(MediaType.self, forKey: .mediaType)
        source = try container.decode(AWMediaSource.self, forKey: .source)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(title, forKey: .title)
        try container.encode(identifier, forKey: .identifier)
        try container.encode(mediaType, forKey: .mediaType)
        print("Probuje obrazek")
        let imageData = NSKeyedArchiver.archivedData(withRootObject: image as Any)
        print("zrobilem obrazek")
        try container.encode(imageData, forKey: .image)
        print("Przeszedlem obrazek")
        try container.encode(source, forKey: .source)
    }

}

以及保存收藏夹数组的方法

static private let key = "favouritesKey"

var favourites: [AWFavourite]!

private func saveFavourites(_ completion: (() -> Void)?) {
        DispatchQueue.global(qos: .background).async {
            do {
                print("Step 1")
                let data = try JSONEncoder().encode(self.favourites)
                print("Step 2") // Most often the freezing occurs here and Step 3 gets printed after few seconds
                UserDefaults.standard.set(data, forKey: AWFavouriteManager.key)
                print("Step 3") // Step 3 gets printed but Step 4 is printed after few seconds, sometimes even more than 20
                DispatchQueue.main.async {
                    print("Step 4\n")
                    completion?()
                }
            } catch let error {
                print("*** \(error.localizedDescription) ***") // No error is ever thrown here, app just freezes
            }
        }
    }

// This is called in init
    func loadFavourites() {
        favourites = []
        guard let data = UserDefaults.standard.data(forKey: AWFavouriteManager.key) else {
            return
        }
        do {
            favourites = try JSONDecoder().decode([AWFavourite].self, from: data)
            print(favourites.map({$0.mediaType.rawValue}))
        } catch let error {
            print("*** \(error.localizedDescription) ***")
        }
    }

0 个答案:

没有答案