等待其他进程
Wait for other processes
我必须等待多个后台进程才能执行其他操作,我正在寻找并尝试用它做点什么,但我做不到。这是代码。我评论了部分以解释我想要达到的目标。我可以用完成处理程序来完成,但是这个函数被调用了几次,具体取决于照片的数量。
func prepareArray(stext: NSMutableAttributedString, completionHandler: CompletionHandler) {
self.finalForUpload = [String]()
var attributedArray = [AnyObject]()
var lastRng = 0
let range:NSRange = NSMakeRange(0,stext.length)
stext.enumerateAttributesInRange(range, options: NSAttributedStringEnumerationOptions(rawValue: 0), usingBlock: {(dic: [String:AnyObject]?, range :NSRange!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
let attachement = dic as NSDictionary!
attachement.enumerateKeysAndObjectsUsingBlock({ (key:AnyObject?, obj:AnyObject?, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
let stri = key as! NSString!
if stri == "NSAttachment"{
let att:NSTextAttachment = obj as! NSTextAttachment
if att.image != nil{
print("range location: \(range.location)")
if range.location != lastRng {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, range.location-lastRng)))
lastRng = range.length
}
let im:UIImage = att.image!
self.httpManager.uploadPhoto(im, completionHandler: { (imgName) -> Void in
let imName = imgName.characters.dropFirst()
let imageName = String(imName.dropLast())
//WAIT FOR THIS
dispatch_async(dispatch_get_main_queue(), {
print("append")
//stext.attributedSubstringFromRange(range)
attributedArray.append(imageName)
lastRng = range.location
})
})
}
}
})
})
//BEFORE DOING THIS
dispatch_async(dispatch_get_main_queue(), {
if lastRng == 0 && attributedArray.count < 1{
attributedArray.append(stext)
} else {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, stext.length-lastRng)))
}
for var i = 0; i<attributedArray.count; i++ {
print("\n \n \(i) : \(attributedArray[i])")
}
})
}
主队列是一个串行队列,也就是说它以先进先出的顺序一次块执行。枚举中的所有调度都应该在底部的 运行.
之前完成
编辑:刚刚注意到您在完成处理程序中异步。
一件简单的事情就是倒数(因为你知道有多少)。
只需在枚举之前添加 var expectedCompletions = attachement.count
,然后在块内将它们倒数 (expectedCompletions--
)。到0时,运行最后的代码。
I have to wait for multiple background process before doing other
您真的应该考虑使用 NSOperationQueue
来满足此要求,因为它允许您配置所有已注册操作之间的依赖关系。通过这种方式,您可以配置和添加多个下载,然后配置依赖于所有这些下载的 post 下载操作。操作队列将在所有其他操作完成后处理开始该操作。
这些操作还为您提供了一种很好的方式来取消挂起的上传/下载(如果您不再需要它们)。
您也可以考虑使用 dispatch_group
s 来管理它。很难确保您所做的完全正确。
您可以使用 dispatch_group
methods 执行此操作。
但是我建议使用类似 PromiseKit 或类似的东西,它可以让您更好地控制多个异步块的依赖关系。
这是您使用 dispatch_group
方法的代码:
func prepareArray(stext: NSMutableAttributedString, completionHandler: CompletionHandler) {
// create the dispatch group
dispatch_group_t aGroup = dispatch_group_create();
self.finalForUpload = [String]()
var attributedArray = [AnyObject]()
var lastRng = 0
let range:NSRange = NSMakeRange(0,stext.length)
stext.enumerateAttributesInRange(range, options: NSAttributedStringEnumerationOptions(rawValue: 0), usingBlock: {(dic: [String:AnyObject]?, range :NSRange!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
let attachement = dic as NSDictionary!
attachement.enumerateKeysAndObjectsUsingBlock({ (key:AnyObject?, obj:AnyObject?, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
let stri = key as! NSString!
if stri == "NSAttachment"{
let att:NSTextAttachment = obj as! NSTextAttachment
if att.image != nil{
print("range location: \(range.location)")
if range.location != lastRng {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, range.location-lastRng)))
lastRng = range.length
}
let im:UIImage = att.image!
// use dispatch_group to coordinate.
// must call before uploadPhoto as we don't know how long it will take
dispatch_group_enter(aGroup);
self.httpManager.uploadPhoto(im, completionHandler: { (imgName) -> Void in
let imName = imgName.characters.dropFirst()
let imageName = String(imName.dropLast())
dispatch_async(aGroup, dispatch_get_main_queue(), {
print("append")
//stext.attributedSubstringFromRange(range)
attributedArray.append(imageName)
lastRng = range.location
// indicate block has completed (reduced group count)
dispatch_group_leave(aGroup);
})
})
}
}
})
})
// wait for all items in group to finish before running this block
dispatch_group_notify(aGroup, dispatch_get_main_queue(), {
if lastRng == 0 && attributedArray.count < 1{
attributedArray.append(stext)
} else {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, stext.length-lastRng)))
}
for var i = 0; i<attributedArray.count; i++ {
print("\n \n \(i) : \(attributedArray[i])")
}
})
}
我必须等待多个后台进程才能执行其他操作,我正在寻找并尝试用它做点什么,但我做不到。这是代码。我评论了部分以解释我想要达到的目标。我可以用完成处理程序来完成,但是这个函数被调用了几次,具体取决于照片的数量。
func prepareArray(stext: NSMutableAttributedString, completionHandler: CompletionHandler) {
self.finalForUpload = [String]()
var attributedArray = [AnyObject]()
var lastRng = 0
let range:NSRange = NSMakeRange(0,stext.length)
stext.enumerateAttributesInRange(range, options: NSAttributedStringEnumerationOptions(rawValue: 0), usingBlock: {(dic: [String:AnyObject]?, range :NSRange!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
let attachement = dic as NSDictionary!
attachement.enumerateKeysAndObjectsUsingBlock({ (key:AnyObject?, obj:AnyObject?, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
let stri = key as! NSString!
if stri == "NSAttachment"{
let att:NSTextAttachment = obj as! NSTextAttachment
if att.image != nil{
print("range location: \(range.location)")
if range.location != lastRng {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, range.location-lastRng)))
lastRng = range.length
}
let im:UIImage = att.image!
self.httpManager.uploadPhoto(im, completionHandler: { (imgName) -> Void in
let imName = imgName.characters.dropFirst()
let imageName = String(imName.dropLast())
//WAIT FOR THIS
dispatch_async(dispatch_get_main_queue(), {
print("append")
//stext.attributedSubstringFromRange(range)
attributedArray.append(imageName)
lastRng = range.location
})
})
}
}
})
})
//BEFORE DOING THIS
dispatch_async(dispatch_get_main_queue(), {
if lastRng == 0 && attributedArray.count < 1{
attributedArray.append(stext)
} else {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, stext.length-lastRng)))
}
for var i = 0; i<attributedArray.count; i++ {
print("\n \n \(i) : \(attributedArray[i])")
}
})
}
主队列是一个串行队列,也就是说它以先进先出的顺序一次块执行。枚举中的所有调度都应该在底部的 运行.
之前完成编辑:刚刚注意到您在完成处理程序中异步。
一件简单的事情就是倒数(因为你知道有多少)。
只需在枚举之前添加 var expectedCompletions = attachement.count
,然后在块内将它们倒数 (expectedCompletions--
)。到0时,运行最后的代码。
I have to wait for multiple background process before doing other
您真的应该考虑使用 NSOperationQueue
来满足此要求,因为它允许您配置所有已注册操作之间的依赖关系。通过这种方式,您可以配置和添加多个下载,然后配置依赖于所有这些下载的 post 下载操作。操作队列将在所有其他操作完成后处理开始该操作。
这些操作还为您提供了一种很好的方式来取消挂起的上传/下载(如果您不再需要它们)。
您也可以考虑使用 dispatch_group
s 来管理它。很难确保您所做的完全正确。
您可以使用 dispatch_group
methods 执行此操作。
但是我建议使用类似 PromiseKit 或类似的东西,它可以让您更好地控制多个异步块的依赖关系。
这是您使用 dispatch_group
方法的代码:
func prepareArray(stext: NSMutableAttributedString, completionHandler: CompletionHandler) {
// create the dispatch group
dispatch_group_t aGroup = dispatch_group_create();
self.finalForUpload = [String]()
var attributedArray = [AnyObject]()
var lastRng = 0
let range:NSRange = NSMakeRange(0,stext.length)
stext.enumerateAttributesInRange(range, options: NSAttributedStringEnumerationOptions(rawValue: 0), usingBlock: {(dic: [String:AnyObject]?, range :NSRange!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
let attachement = dic as NSDictionary!
attachement.enumerateKeysAndObjectsUsingBlock({ (key:AnyObject?, obj:AnyObject?, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
let stri = key as! NSString!
if stri == "NSAttachment"{
let att:NSTextAttachment = obj as! NSTextAttachment
if att.image != nil{
print("range location: \(range.location)")
if range.location != lastRng {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, range.location-lastRng)))
lastRng = range.length
}
let im:UIImage = att.image!
// use dispatch_group to coordinate.
// must call before uploadPhoto as we don't know how long it will take
dispatch_group_enter(aGroup);
self.httpManager.uploadPhoto(im, completionHandler: { (imgName) -> Void in
let imName = imgName.characters.dropFirst()
let imageName = String(imName.dropLast())
dispatch_async(aGroup, dispatch_get_main_queue(), {
print("append")
//stext.attributedSubstringFromRange(range)
attributedArray.append(imageName)
lastRng = range.location
// indicate block has completed (reduced group count)
dispatch_group_leave(aGroup);
})
})
}
}
})
})
// wait for all items in group to finish before running this block
dispatch_group_notify(aGroup, dispatch_get_main_queue(), {
if lastRng == 0 && attributedArray.count < 1{
attributedArray.append(stext)
} else {
attributedArray.append(stext.attributedSubstringFromRange(NSMakeRange(lastRng, stext.length-lastRng)))
}
for var i = 0; i<attributedArray.count; i++ {
print("\n \n \(i) : \(attributedArray[i])")
}
})
}