Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在执行另一个块之前执行所有后台线程_Ios_Multithreading_Core Data_Semaphore_Background Thread - Fatal编程技术网

Ios 在执行另一个块之前执行所有后台线程

Ios 在执行另一个块之前执行所有后台线程,ios,multithreading,core-data,semaphore,background-thread,Ios,Multithreading,Core Data,Semaphore,Background Thread,我正在尝试在核心数据中加载照片,但这需要一些后台线程,所以碰巧我的对象保存在核心数据中而没有照片,我得到的照片为零。我的团队的照片也是如此 简言之,在每次迭代中,我都会在核心数据中保存一个对象,并且保存速度比加载照片数据快 我试过信号灯、屏障、群组,。。。但都不管用。我确实做错了什么,但我不知道是什么。如果有人能帮助我,我会非常感激,我已经两个星期都在努力解决这个问题了。这是我的代码的简化版本,完整版本可在下面访问: // MARK - ViewDidLoad override func vie

我正在尝试在核心数据中加载照片,但这需要一些后台线程,所以碰巧我的对象保存在核心数据中而没有照片,我得到的照片为零。我的团队的照片也是如此

简言之,在每次迭代中,我都会在核心数据中保存一个对象,并且保存速度比加载照片数据快

我试过信号灯、屏障、群组,。。。但都不管用。我确实做错了什么,但我不知道是什么。如果有人能帮助我,我会非常感激,我已经两个星期都在努力解决这个问题了。这是我的代码的简化版本,完整版本可在下面访问:

// MARK - ViewDidLoad
override func viewDidLoad() {
    // This method is only called once, so you want to create any controls or arrays here
    super.viewDidLoad()

    // Verifying connectivity to internet
    if Reachability.isConnectedToNetwork() == true {

    // Getting data from Parse + getDataInBackgroundWithBlock

    }else{

    }
}


// MARK - Action of the login button
@IBAction func loginBtn_click(sender: AnyObject) {
    if usernameTxt.text == "" || passwordTxt.text == "" {
        self.displayAlert("Error", message: "Please enter a username and password")
    }else{

        // MARK - Login the user
        PFUser.logInWithUsernameInBackground(usernameTxt.text!, password: passwordTxt.text!) { (user, error) -> Void in

            if error == nil {

                let queue = dispatch_queue_create("com.karagan.app.queue", DISPATCH_QUEUE_CONCURRENT)

                dispatch_async(queue, { () -> Void in
                    self.getObjectsFromQueryWithAscendingOrder("Add", key: "user", value: userName, ascendingOrder: "added", completionHandler: { (objects1) -> Void in

                // Update of an array in background 

                    })
                })



                dispatch_async(queue, { () -> Void in

               // Update of an array in background

                })



                dispatch_async(queue, { () -> Void in
                    self.getObjectsFromQueryWithAscendingOrder("Group", key: "membersUsername", value: userName, ascendingOrder: "membersUsername", completionHandler: { (objects3) -> Void in

                 // Update of an array in background

                        // MARK - Adding all the users in Core data
                        for var i = 0; i < usersFromParseDataBase.count; i++ {

                            let entity = NSEntityDescription.entityForName("Users", inManagedObjectContext: self.managedObjectContext)
                            let newUser = Users(entity: entity!, insertIntoManagedObjectContext: self.managedObjectContext)
                            if self.arrayAddedUsers.contains(usersFromParseDataBase[i].username){

                // Saving new records in Core Data                  

                            }
                        }
                    })
                })

                dispatch_async(queue, { () -> Void in
                    self.getObjectsFromQueryWithDescendingOrder("Group", key: "membersUsername", value: userName, descendingOrder: "conversationUpdate", completionHandler: { (objects4) -> Void in

                            if array.count == 2 {

                    // Getting data in background - photo.getDataInbackgroundWithBlock                  

                                }
                            }else{

                // Getting data in background - photo.getDataInbackgroundWithBlock

                            }
                        }
                    })
                })

                dispatch_barrier_async(queue, { () -> Void in

        // Doing some stuff in background which needs the data from threads above 

                })

            }else{
                // Print error from loginWithUsernaemInBackground
            }
        }
    }
}

问题是,我需要这些数据用于以后的其他操作。我的代码不一致。

我认为你的思路是对的。当我创建一个简单的程序并使用
dispatch\u barrier\u async
时,它可以完美地工作:

let queue = dispatch_queue_create("com.karagan.app.queue", DISPATCH_QUEUE_CONCURRENT)

dispatch_async(queue, { () -> Void in
    sleep(1)
    print("1")
})

dispatch_async(queue, { () -> Void in
    sleep(2)
    print("2")
})

dispatch_async(queue, { () -> Void in
    sleep(3)
    print("3")
})

dispatch_async(queue, { () -> Void in
    sleep(4)
    print("4")
})

dispatch_barrier_async(queue, { () -> Void in
    print("done")
})
输出:

1
2
3
4
done
我认为问题在于
dispatch\u async
没有等待调用
PFFile.getDataInBackgroundithBlock
完成:

photoFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
    if error == nil {
        self.arrayImageFiles.append(imageData!)
        print("Loading group image")
    }
})
尝试将所有调用切换到
getdatainbackgroundithblock
,而改为同步调用
PFFile.getData
(:):


这实际上不应该有任何性能问题,因为您已经在异步执行此代码。

您可能需要查看dispatch\u group\u create()、dispatch\u group\u wait()和dispatch\u group\u async(),以便获得一组要在继续之前等待完成的任务。此链接可能会有所帮助:如果要分派的代码块本身是异步任务,则可能必须显式地
dispatch\u group\u enter
/
离开
。如果不查看生成这些日志消息的代码,就很难诊断问题或进一步提出建议。或者,坦率地说,因为您的代码非常复杂,您可能希望构造一个能够体现您所描述的bug类型的代码。你好,Rob,我添加了一个简单版本的代码,其中只包含最重要的部分。它全面吗?如果没有,我可以试着简化。谢谢你的帮助。dee zg,我已经试过调度组创建()。。。但我还是有同样的问题。只是我不知道如何正确地实现它。我总是遇到同样的问题,除非我在最后一个区块中添加“sleep(Uint32)”,但这并不一致。如果有人找到了我问题的解决方案,我会非常感激,因为已经有3-4周的时间了,我一直在解决这个问题,不幸的是,关于堆栈溢出的任何问题都没有帮助。谢谢Mark的回答。我还需要做一些测试,但这可能会对我有所帮助。我不知道可以在主线程上加载图像数据。我非常感谢您的帮助,如果它真的解决了我的问题,我会通知您。如果以前提交到同一队列的任务是同步的,则使用
调度\u barrier\u async
只能用作“哨兵”。但在OPs中,它们是异步的。也就是说,调用立即返回,对于队列,此块已完成。@CouchDeveloper这就是我在回答中所说的,也是我建议同步这些任务的原因。我遗漏了什么吗?网络请求不应同步执行。一种可行的方法是使用@dezg在其对OPs问题的评论中建议的调度组。链接指出的答案是正确的,并且解释得很好。因此,在这种情况下,由于网络调用是在异步块中完成的,因此不应该冻结UI,但它将强制每个块中的图像等待加载同一块中的前一个图像。
photoFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
    if error == nil {
        self.arrayImageFiles.append(imageData!)
        print("Loading group image")
    }
})
var imageData = photoFile.getData
if (imageData != nil) {
    self.arrayImageFiles.append(imageData!)
}