删除和图像并再次重新写入会产生错误
Deleting and Image and Re-Writing it back again produces errors
我正在尝试构建一个应用程序,用户可以在其中处理图像并创建包含多个具有相应值的图像的结构。当用户填写所有信息并按保存时,生成结构,然后图像保存在 FileManager.default 中,其余信息保存在用户默认值中:
guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return
}
let imageName = name+"_"+String(banknote.key)+".png"
let imgPath = documentDirectoryPath.appendingPathComponent(imageName)
do {
try banknote.value.pngData()?.write(to: imgPath)
self.imageLoc[banknote.key] = imageName
} catch {
print("its an error")
}
然后我使用一个函数将每个实例的图像拉回 UIImages,如果需要的话,如下所示:
func getImages() -> [Int:UIImage]{
var unarchivedImages = [Int:UIImage]()
if !self.images.isEmpty {
let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
for imageLoc in images{
let imageURL = documentDirectoryPath.appendingPathComponent(imageLoc.value)
let image = UIImage(contentsOfFile: imageURL.path)
unarchivedImages[imageLoc.key] = image
}
}
然而,当用户想要更新实例时,就会出现问题,比如更改其中的一些其他变量。我的程序是先像这样删除图像:
let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
for imageLoc in images{
let imageURL = documentDirectoryPath.appendingPathComponent(imageLoc.value)
if FileManager.default.fileExists(atPath: imageURL.path){
try? FileManager.default.removeItem(atPath: imageURL.path)
} else {
print("failed")
}
}
然后创建一个新实例并像第一段代码一样再次保存。但是,如果我使用上面显示的删除程序,保存图像不再有效并显示错误:
CreateDataWithMappedFile:1429: 'open' 失败 '/var/mobile/Containers/Data/Application/83615D52-A4E7-4930-ABE3-B3702AC294F2/Documents/h_1.png' 错误 = 2(没有这样的文件或目录)
handle_write_error:103: 流错误
handle_write_error:103: 没有 IDAT 写入文件
有什么想法吗?
经过几个小时的徒劳调试,我发现了问题所在。问题是通过 UIImage(contentsOfFile: ...) 和 UIImage(named: ...) 初始化和传递图像都保留对文件的引用,而不是保留数据,这更重要,因为引用最终得到删除,而它是传递的数据。因此,解决方案是使用:
let imageData = try? Data(contentsOf: imageURL)
let image = UIImage(data: imageData!)
我正在尝试构建一个应用程序,用户可以在其中处理图像并创建包含多个具有相应值的图像的结构。当用户填写所有信息并按保存时,生成结构,然后图像保存在 FileManager.default 中,其余信息保存在用户默认值中:
guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return
}
let imageName = name+"_"+String(banknote.key)+".png"
let imgPath = documentDirectoryPath.appendingPathComponent(imageName)
do {
try banknote.value.pngData()?.write(to: imgPath)
self.imageLoc[banknote.key] = imageName
} catch {
print("its an error")
}
然后我使用一个函数将每个实例的图像拉回 UIImages,如果需要的话,如下所示:
func getImages() -> [Int:UIImage]{
var unarchivedImages = [Int:UIImage]()
if !self.images.isEmpty {
let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
for imageLoc in images{
let imageURL = documentDirectoryPath.appendingPathComponent(imageLoc.value)
let image = UIImage(contentsOfFile: imageURL.path)
unarchivedImages[imageLoc.key] = image
}
}
然而,当用户想要更新实例时,就会出现问题,比如更改其中的一些其他变量。我的程序是先像这样删除图像:
let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
for imageLoc in images{
let imageURL = documentDirectoryPath.appendingPathComponent(imageLoc.value)
if FileManager.default.fileExists(atPath: imageURL.path){
try? FileManager.default.removeItem(atPath: imageURL.path)
} else {
print("failed")
}
}
然后创建一个新实例并像第一段代码一样再次保存。但是,如果我使用上面显示的删除程序,保存图像不再有效并显示错误:
CreateDataWithMappedFile:1429: 'open' 失败 '/var/mobile/Containers/Data/Application/83615D52-A4E7-4930-ABE3-B3702AC294F2/Documents/h_1.png' 错误 = 2(没有这样的文件或目录)
handle_write_error:103: 流错误
handle_write_error:103: 没有 IDAT 写入文件
有什么想法吗?
经过几个小时的徒劳调试,我发现了问题所在。问题是通过 UIImage(contentsOfFile: ...) 和 UIImage(named: ...) 初始化和传递图像都保留对文件的引用,而不是保留数据,这更重要,因为引用最终得到删除,而它是传递的数据。因此,解决方案是使用:
let imageData = try? Data(contentsOf: imageURL)
let image = UIImage(data: imageData!)