我正在尝试使用用户之前上传的图像填充UITableView。 使用CoreData将图像作为二进制数据存储在用户设备上(已启用外部存储)。
首先,应用程序从contactsArray中的CoreData获取数据。该函数在viewDidLoad中调用
func loadContacts() {
let request : NSFetchRequest<ProfileData> = ProfileData.fetchRequest()
do {
contactsArray = try context.fetch(request)
} catch {
print("Error fetching data from context: \(error)")
}
}
然后填充TableView-Cells。
cell.contactNameLabel?.text = contactsArray[indexPath.row].contactsName
if let data = self.contactsArray[indexPath.row].photo {
cell.contactImageView.image = UIImage(data:data)
}
if cell.contactImageView.image == nil {
cell.contactImageView.image = UIImage(named: "blank_Profile.jpg")
}
通过这种方式,TableView的滞后性超过了我以前见过的一切。 因此,我尝试将图像加载到“ cellForRowAt indexPath”函数之外。
getImages()在viewDidLoad中的loadContacts()之后立即被调用。它将二进制数据转换为UIImages并将它们放入一个数组中,然后在cellForRowAt indexPath中使用它。
func getImages(){
var i = 0
while i < contactsArray.count {
print(i)
if let data = contactsArray[i].photo {
imageArray.append(UIImage(data:data)!)
}
if contactsArray[i].photo == nil {
imageArray.append(UIImage(named: "blank_Profile.jpg")!)
}
i += 1
}
}
...
cell.contactImageView.image = imageArray[indexPath.row]
现在问题出在另一个地方。 该应用程序现在需要15秒钟以上才能启动。 如果有人可以告诉我该如何使该应用程序快速有效地运行,我将感到非常高兴。
答案 0 :(得分:0)
所以我想知道您的提取请求是什么样的,这可能是一个痛苦的问题。
我可能会建议使用NSFetchedResultsController
很难比这更优化。对于NSFetchedResultsController
并不难找到教程,但是this是我最后使用的教程。
同样,我可能会一起放弃getImages()
。只需在配置单元的任何地方处理该逻辑。
if let contact = contactsArray[indexPath.row] {
cell.contactNameLabel?.text = contact.contactsName
if let imageData = contact.data, let contactImage = UIImage(data: imageData) {
cell.contactImageView.image = contactImage
} else {
cell.contactImageView.image = // #imageLiteral(resourceName: "blank_Profile.jpg")
}
}
我可能只是通过单元的接触,然后让单元进行配置,但这很大程度上取决于设计选择。对此有很多选择和意见。
如果您决定保留getImages()
,则可以尝试以下另一种方法:
func getImages() {
for (_, contact) in contactsArray.enumerated() {
if let data = contact.photo, let image = UIImage(data:data) {
imageArray.append(image)
continue
}
let profilePlaceholder = // #imageLiteral(resourceName: "blank_Profile.jpg")
imageArray.append(profilePlaceholder)
}
}
但是同样有很多不同的方法可供选择。
我希望这会有所帮助! 祝你好运,编码愉快!
答案 1 :(得分:0)
Ypu需要将图像存储在文档目录中的缓存中,并将该缓存的路径存储在核心数据中。从核心数据加载图像是一项艰巨的任务。
答案 2 :(得分:0)
cell.contactNameLabel?.text = contactsArray[indexPath.row].contactsName
if let data = self.contactsArray[indexPath.row].photo {
DispatchQueue.global(qos: .background).async {
// fetch the image data
// if data fetched, the update the image
if fetched {
DispatchQueue.main.async {
// update the fetched data. this way you can load more faster. and image
// pulling happens in the background.
// NOTE: Additionally you can cache this image in memory to load more faster when scrolling
}
} else {
DispatchQueue.main.async {
// If something went wrong while fetching image
// show the placeholder in the here
}
}
}
}