- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序有一个 UITableView,其单元格包含一个 UICollectionView subview (未重用)。 collectionView 的单元格有一个 UIImageView 来保存图片。我试图一次下载所有图像,将它们存储在一个数组中,然后在 所有图像下载完毕 后在 collectionView 单元格中显示数组的内容。在 ObjC 中,我已经使用 NSURLConnection
多次执行此操作,但我正在尝试使用 Swift 和 NSURLConnection
来实现此目的,但我遇到了我认为可能是并发性或语义问题。也许你们中的某个人可以指出我正确的方向,因为我觉得我在这上面花了太多时间。
在包含我调用的 collectionView 的 UITableView 的单元格子类中
func downloadPhotosWithURLs(urls: [String]) {
var imagesMutableArray = NSMutableArray()
for url in urls {
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!, completionHandler: { (data, repsonse, err) -> Void in
if let imgData = data {
if let image = UIImage(data: imgData) {
imagesMutableArray.addObject(image)
}
else {
// PUT IN "Photo Unavailable" Pic
}
}
else {
// PUT IN "Photo Unavailable" Pic
}
}).resume()
}
// UPDATE (but async op not done)
if let downloadedImages: [UIImage] = imagesMutableArray as NSArray as? [UIImage] {
self.images = downloadedImages
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.collectionView.reloadData()
})
}
}
问题是当我要求重新加载 collectionView 时,图像还没有被获取。 for 循环中的异步操作肯定是罪魁祸首。我如何调用我的 //UPDATE
代码 after 所有图像都已下载?
最佳答案
如果要等待一系列异步任务完成,创建一个dispatch_group_t
,在每次请求开始前入组,completion block 中离开组,然后就可以依赖dispatch_group_notify
当每个“enter”与“leave”匹配时调用
func downloadPhotosWithURLs(urls: [String]) {
var images = [UIImage]()
let group = dispatch_group_create()
for url in urls {
dispatch_group_enter(group)
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!, completionHandler: { data, response, error in
if let imgData = data {
if let image = UIImage(data: imgData) {
dispatch_sync(dispatch_get_main_queue()) {
images.append(image)
}
} else {
// PUT IN "Photo Unavailable" Pic
}
} else {
// PUT IN "Photo Unavailable" Pic
}
dispatch_group_leave(group)
}).resume()
}
// UPDATE
dispatch_group_notify(group, dispatch_get_main_queue()) {
self.images = images
self.collectionView.reloadData()
}
}
请注意,您确实应该同步图像数组的更新(可变数组不是线程安全的)。
--
满怀希望地回答了这个问题,我必须承认我可能会建议两个进一步但重要的改变:
您不应将图像保存在数组中(因为如果数量太多,您可能会耗尽内存)。 JPEG 或 PNG 文件可能看起来不太大,但当图像在 RAM 中解压缩时,它们会占用大量内存,您很容易收到内存警告。
您可能会考虑将图像下载到持久存储中,而不是内存中。如果您想将图像保存在内存中,请出于性能原因使用 NSCache
(但在出现内存警告时将其清除)。
如果您没有太多图片,或者它们都很小,这可能并不重要。但是,如果您正在寻找可扩展的解决方案,则不需要您的应用将所有图像保存在一个数组中。
您可能不希望在重新加载 Collection View 之前等待所有图像。通常人们会建议延迟加载。因此,如果您有 1000 张图像,但一次只能看到 20 张,为什么要等待 1000 张图像呢?专注于加载可见细胞的图像。此外,您可能希望看到图像在下载时弹出到 Collection View 中(因此不要等待前 20 张可见图像下载完毕,而是在它们进入时显示它们)。
您通常通过让 cellForItemAtIndexPath
异步启动图像下载并在完成后更新单元格来完成此操作。
关于ios - For 循环中的 NSURLSession 下载图像数据然后添加到 NSMutableArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32194003/
我编写了一个提供一些数据的 REST 服务。它受密码保护。 我正在尝试编写一个后台进程来获取数据并将其填充到我在应用程序中拥有的 sqlLite 数据库中。 我最初是在没有身份验证的情况下使用的: -
我想要一个 API key 并验证用户身份。我在控制台中看到消息“ session URL 任务成功:HTTP 200”。不幸的是,我总是收到页面“{”消息“:”的消息。此请求“}”的授权已被拒绝。我
我为 NSURLSession 创建了类别,然后我遇到了一个问题。在 iOS 7 中,[[NSURLSession sharedSession] isKindOfClass:[NSURLSession
如何从 NSHTTPCookieStorage.sharedHTTPCookieStorage 中删除所有 cookie?我知道删除单个指定 cookie 的唯一方法,但是,这些 cookie 是由
我正在尝试在应用程序进入后台(例如从主页按钮按下)的情况下正确处理进程内 NSURLSessionTasks。我目前正在采用将进程中的任务复制到后台队列的方法(请参见下面的代码)。然而,我发现后台任务
我是 objective-c 中的新手,使用 iOS 9 Xcode 7.2 并收到此警告“'initWithRequest:delegate:'已弃用:在 iOS 9.0 中首次弃用 - 使用 NS
当我导入 Gmail API 的 GTL.xcodeproj 并运行它时出现上述错误。我正在使用 Xcode 7.1 beta 并且在 Gmail API 二进制文件的头文件中出现了很多错误我们不推荐
我在我的 iOS 应用程序中使用 Alamofire 进行网络连接。我需要在 iOS 7+ 中运行这个应用程序。我要在状态栏中指示网络事件 ,所以我创建了这个结构: struct ActivityMa
我需要从服务器下载视频并保存视频以供稍后观看。 所以我需要下载视频并将其使用自定义名称保存在应用程序的文件系统中,到目前为止我可以下载数据(我猜)但无法存储它。 不,我不想使用额外的扩展框架或其他什么
在一个小型 iOS 应用程序中,我需要从服务器检索一些 JSON(类似于 DNS 请求),并使用此响应来发起进一步的连接。为此,我有一个使用 NSURLSession 处理 JSON 请求的对象。该对
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
当我尝试在网络离线(飞行模式)时启动基本的 NSURLSession 传输时,使用 NSURLSessionConfiguration defaultSessionConfiguration 和 ep
我曾经用 NSURLConnection 做我想做的事. 我会创建一个新的自定义 NSOperation对象 设置我的 NSMutalbeRequest当准备好触发operation女巫会排队操作..
我创建了一个下载任务。我已经使用cancelByProducingResumeData在应用程序中取消了任务,并将其保存到磁盘。当用户重新启动应用程序并单击“恢复”按钮时,我再次通过self.down
即使在使 NSURLSession 无效后,使用 Instruments 运行配置文件,一些名为 TubeManager、HTTPConnectionCache 和 HTTPConnectionCac
我有一段普通的代码,我几乎在我的代码中到处使用: let configuration = URLSessionConfiguration.default let session = URLSessio
我希望有人能够帮助我理解在我的 WatchOS 2 应用程序中尝试实现 NSURLSession 时遇到的问题。 无论出于何种原因,我收到错误; Error Domain=NSCocoaErrorDo
我正在尝试使用 NSURLSession 从 URL 获取 ID,但是 let task = NSURLSession.... 和 task.resume 之间的代码 永远不会执行(我在里面放置了一个
我正在尝试使用 NSURLSession 发出 HTTPRequest。当我设置完整的 url 时,请求返回正确的数据,但是当使用参数时 (NSJSONSerialization.dataWithJS
我是这方面的新手,但过去常常在这里搜索特定的东西,并且由于我找不到特定的答案,也许这里有人可以提供帮助。 我基本上是在学习和构建一个应用程序。 目前我已经构建登录、注册 View Controller
我是一名优秀的程序员,十分优秀!