标签: grand-central-dispatch

GCD:如何从两个线程写入和读取变量

这可能听起来像一个新手问题,我是GCD的新手,

我正在创建并运行以下两个线程.第一个将数据放入ivar mMutableArray,第二个读取数据.如何锁定和取消线程以避免崩溃并保持代码线程安全?

// Thread for writing data into mutable array 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer) {
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), interval * NSEC_PER_SEC, leeway);
    dispatch_source_set_event_handler(timer, ^{
        ...
        // Put data into ivar
        [mMutableArray addObject:someObject];
        ...
    });
    dispatch_resume(timer);
}

// Thread for reading from mutable array
dispatch_source_t timer1 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer1) {
    dispatch_source_set_timer(timer1, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), interval * NSEC_PER_SEC, leeway);
    dispatch_source_set_event_handler(timer1, ^{
        ...
        if …
Run Code Online (Sandbox Code Playgroud)

iphone multithreading objective-c grand-central-dispatch ipad

1
推荐指数
1
解决办法
1952
查看次数

关于使用调度队列同步主线程的问题

在预取数据和在uitableview上显示时遇到问题.所以基本上我想阻止主UI线程,以便我可以从Web获取数据.我正在使用串行调度队列进行同步.此外,调度队列块正在执行从Web获取数据的另一个块.执行代码是用viewdidload编写的:

dispatch_queue_t queue= dispatch_queue_create("myQueue", NULL);


CMStore *store = [CMStore defaultStore];

// Begin to fetch all of the items
dispatch_async(queue, ^{

[store allObjectsOfClass:[Inventory class]
       additionalOptions:nil
                callback:^(CMObjectFetchResponse *response) {

                    //block execution to fetch data

                }];
});
dispatch_async(queue, ^{
//load data on local data structure


    [self.tableView reloadData];
});
Run Code Online (Sandbox Code Playgroud)

uitableview grand-central-dispatch ios objective-c-blocks

1
推荐指数
1
解决办法
2446
查看次数

为什么GCD会增加执行时间?

我尝试学习Grand Central Dispatch(GCD)并使用以下代码进行测试:

使用GCD:

#include <dispatch/dispatch.h>
#include <vector>
#include <cstdlib>
#include <iostream>

int main(int argc, char *argv[])  
{
   const int N = atoi(argv[1]);
   __block std::vector<int> a(N, 0);
   dispatch_apply(N, 
     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
     ^(size_t i) 
     { 
       a[i] = i;
#ifdef DEBUG           
       if ( i % atoi(argv[2]) == 0)
         std::cout << a[i] <<  std::endl;
#endif
     });
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

没有GCD:

#include <vector>
#include <cstdlib>
#include <iostream> 

int main(int argc, char *argv[]) 
{
  const int N = atoi(argv[1]);
  std::vector<int> a(N, 0);
  for (int i = …
Run Code Online (Sandbox Code Playgroud)

c++ grand-central-dispatch clang++

1
推荐指数
1
解决办法
612
查看次数

更快地加载 UIImagePickerController?

我需要UIImagePickerController更快地加载。我的应用程序UIImagePickerController可能会从多个控制器调用,并且在每个控制器中有两个按钮,一个用于照片库,另一个用于相机。这是我的示例应用程序。Apple 在“并发编程指南”中推荐了我尝试过的一些解决方案。
最简单的方法是在用户按下按钮时分配和初始化一个实例。这最多可能需要 2 秒才能显示相机。
解决方案尝试:-
(1) 我创建了一个@property (...) *imagePicker 并调用了它的 alloc & initviewDidAppear以使其看起来很流畅,但它干扰了其他元素的加载,可能是因为它使用了相同的线程。在initWithNibName或 中使用时结果更糟viewDidLoad
(2) Operation queues... 不令人满意的结果。
(3) Dispatch Queues... 更好的结果,但仍然明显不稳定的性能。
(4)performSelectorInBackground:withObject:结果不大。我不认为我想走向全球,除非另有建议。我制作两个 @properties 没有问题UIImagePickerController。我将继续可能的'线程编程指南'。
如果可以,请在您的解决方案中包含任何必要的内存管理实践。谢谢你。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
// (1) TRYING OPERATION QUEUES
    // (a) --- NSBlockOperation
    NSBlockOperation *NSBO_IP = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"before");
        imagePicker = [[UIImagePickerController alloc] init];
        // 1.9, 1.6, 1.4 seconds pass between 'before' …
Run Code Online (Sandbox Code Playgroud)

multithreading memory-management uiimagepickercontroller grand-central-dispatch ios

1
推荐指数
1
解决办法
2657
查看次数

iOS Core Data dispatch_async 后台排队崩溃

我遇到了不可重现的崩溃,我不知道为什么。我正在后台队列中缓存图像。图像名称是 Core Data NSManagedObject 子类 CCCard 上的属性。同时,我有一个集合视图也在访问这些 CCCard。

这是要遵循的相关代码和注释。

//CCDeckViewController.m --------------------------------------

- (void)viewDidLoad {
    // This will fetch the CCCard objects from Core Data.
    self.cards = [[CCDataManager shared] cards];

    [self cacheImages];
}

- (void)cacheCardImages {
    // Because these are NSManagedObjects, I access them in the background
    // via their object ID. So pull the IDs out here.
    NSArray *cardIds = [self.cards valueForKey:@"objectID"];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        for (NSManagedObjectID *cardId in cardIds) {

            // Fetch the actual CCCard object.
            CCCard *card = …
Run Code Online (Sandbox Code Playgroud)

core-data fault grand-central-dispatch ios nscache

1
推荐指数
1
解决办法
1892
查看次数

QoS 用户交互和更新 UI

在 iOS 上,UI 应该只通过主线程更新,但让我感兴趣的是在文档中,用户交互服务质量定义如下:

与用户交互的工作,例如在主线程上操作、刷新用户界面或执行动画。如果工作没有很快发生,用户界面可能会出现冻结。专注于响应能力和性能。

问题是,如果你dispatch_get_global_queue用那个 QoS调用,返回的队列不会是主队列,对吗?因此,提交到该队列的工作如何刷新 UI?

谢谢你。

multithreading uikit grand-central-dispatch ios

1
推荐指数
1
解决办法
406
查看次数

等待两个异步完成函数完成,然后再执行下一行代码

我有两个功能: func Females_NonChat()func males_NonChat() 我想等他们都在viewDidLoad中执行打印语句之前完成.我需要另一个完成处理程序才能完成吗?

使用的函数是firebase完成处理程序,用于从在线数据库请求信息...

override func viewDidLoad() {
    super.viewDidLoad()
    func Females_NonChat()
    func males_NonChat()

    print("finished executing both asynchronous functions")
}

func Females_NonChat(){
    Anon_Ref.child("Chatting").child("female").observeSingleEventOfType(.Value, withBlock: {(snapshot) in
        if let FemInChatting = snapshot.value as? [String : String] {
            print("executing")
        }
    })
}

func males_NonChat(){
    Anon_Ref.child("Chatting").child("male").observeSingleEventOfType(.Value, withBlock: {(snapshot) in
        print("executing")
    })
}
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch ios completionhandler swift firebase-realtime-database

1
推荐指数
1
解决办法
1230
查看次数

EXIF 的 PHContentEditingInputRequestOptions 阻塞主线程

我正在获取图像 EXIF 以获取 LensMake。

这是我发现这样做的唯一方法:

let lstAssets : PHFetchResult<PHAsset> = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: nil)
lstAssets.enumerateObjects({object , index, stop in
    let options = PHContentEditingInputRequestOptions()
    object.requestContentEditingInput(with: options) { (contentEditingInput: PHContentEditingInput?, _) -> Void in
        let fullImage : CIImage = CIImage(contentsOf: contentEditingInput!.fullSizeImageURL!)!
        if let exif = fullImage.properties["{Exif}"]{ ...
Run Code Online (Sandbox Code Playgroud)

问题在于 requestContentEditingInput 的回调/声明/完成中的代码在主线程中运行,并阻止来自 UI 的任何调用(例如按钮的 IBAction)。因此,如果我以 100 的 lstAssets.count 开始并在 enumerateObjects 中发出 100 个请求,则需要完成所有回调才能在 UI 中执行某些操作。

我尝试将 enumerateObjects 放在 DispatchQueue.global(qos: .background).async 中,但没有成功。如果我将回调代码放在后台线程中,也会发生同样的情况。

奇怪的是,如果我将 PHImageManager.default() 与 requestImageData 用于图像,则这种行为会有所不同,但问题是我无法以这种方式获得 EXIF。

如何解除阻塞队列?有没有更好的方法来获得EXIF?

我在 Xcode 8.2 中运行 Swift 3。 …

multithreading exif grand-central-dispatch ios swift

1
推荐指数
1
解决办法
1271
查看次数

将完成处理程序与 DispatchQueue 一起使用

我了解到并发DispatchQueue允许其中的代码立即返回,因此不会阻塞调用线程。这通常与加载大数据的后台任务一起使用。

我还了解到完成处理程序(例如, in URLSession)允许在某些任务完成后执行处理程序中的代码。

我的问题是:这是否意味着并发调度队列和完成处理程序具有重叠的目的?如果我已经使用了完成处理程序,就不需要用并发调度队列包装它吗?

比如下面是一个使用 URLSession 的耗时的数据加载任务,用并发调度队列包装它是不是一个好主意?

URLSession(configuration: URLSessionConfiguration.default).dataTask(with: propertiesRequest) { data, response, error in
        // print("within dataTask: data: \(data), response: \(response), error: \(error)")
        if let error = error {
            print(error)
        } else if let httpResponse = response as? HTTPURLResponse {
            if httpResponse.statusCode == 200 {
                print("success: property task request")


                do {

                    handler(responseDict, nil) // This is a function supplied by caller

                } catch let error as NSError {
                    handler(nil, error)
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

concurrency grand-central-dispatch completionhandler nsurlsession swift

1
推荐指数
1
解决办法
4275
查看次数

GCD调度组的并发限制是多少?

我一直在使用A DispatchGroup来促进应用程序中的多个并发调用。

我的后端团队注意到,当我尝试进行八个并发呼叫时,它们被分为四个批次的两个批次。

  1. 四个并发呼叫是否限制了GCD?
  2. 这是GCD框架的限制,还是取决于硬件?
  3. 有没有办法允许更多并发呼叫?

grand-central-dispatch ios swift

1
推荐指数
1
解决办法
284
查看次数