标签: grand-central-dispatch

暂停计时器上的dispatch_source_cancel会导致EXC_BAD_INSTRUCTION

我正在尝试取消然后释放暂停的计时器但是当我调用'dispatch_release'时,我立即得到EXC_BAD_INSTRUCTION.

这不是一组有效的计时器吗?

定时器创建和暂停:

@interface SomeClass: NSObject { }
@property (nonatomic, assign) dispatch_source_t             timer;
@end

// Class implementation
@implementation SomeClass

@synthesize timer = _timer;

- (void)startTimer 
{
    dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 
                                    0, 0, globalQ); 

    dispatch_time_t startWhen = dispatch_walltime(DISPATCH_TIME_NOW, NSEC_PER_SEC * 1);
    dispatch_source_set_timer(_timer, startWhen, 1 * NSEC_PER_SEC, 5000ull);

    dispatch_source_set_event_handler(_timer, ^{
        // Perform a task 

        // If a particular amount of time has elapsed, kill this timer
        if (timeConstraintReached)
        {
            // Can I suspend this timer within it's own …
Run Code Online (Sandbox Code Playgroud)

iphone grand-central-dispatch dispatchertimer ios ios5

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

如何修改自定义GCD队列的优先级?

我已经像这样创建了一个GCD队列:

dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL);
Run Code Online (Sandbox Code Playgroud)

当我将任务分派给该队列时,它比在主线程上执行任务要慢.

dispatch_async(q, ^(void) {
    [self performHeavyCalculationAndUpdateUI];
});
Run Code Online (Sandbox Code Playgroud)

我怀疑默认情况下队列的优先级非常低.如何更改此队列的优先级?或者还有什么我必须做的吗?

iphone concurrency grand-central-dispatch ios

18
推荐指数
2
解决办法
1万
查看次数

简单的GCD串行队列示例,例如使用块的FIFO

我阅读了Apple文档,了解如何使用串行队列来确保以可预测的顺序执行任务,但现在我感到困惑太多了.
一些我如何能够连续工作,但我仍然不清楚,所以我需要简单的串行示例,我的方法串行执行.

我将我的功能划分为4个部分,现在希望它们执行Serially

[self ReadAllImagesFromPhotosLibrary];

[self WriteFewImagestoDirectory];

[self GettingBackAllImagesFromFolder]; 

[self MoveToNextView];
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch ios objective-c-blocks

18
推荐指数
3
解决办法
2万
查看次数

何时使用Semaphore而不是Dispatch Group?

我会假设我知道如何使用DispatchGroup,为了解问题,我尝试过:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        performUsingGroup()
    }

    func performUsingGroup() {
        let dq1 = DispatchQueue.global(qos: .userInitiated)
        let dq2 = DispatchQueue.global(qos: .userInitiated)

        let group = DispatchGroup()

        group.enter()
        dq1.async {
            for i in 1...3 {
                print("\(#function) DispatchQueue 1: \(i)")
            }
            group.leave()
        }

        group.wait()

        dq2.async {
            for i in 1...3 {
                print("\(#function) DispatchQueue 2: \(i)")
            }
        }

        group.notify(queue: DispatchQueue.main) {
            print("done by group")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果 - 预期 - 是:

performUsingGroup() DispatchQueue 1: 1
performUsingGroup() DispatchQueue …
Run Code Online (Sandbox Code Playgroud)

semaphore grand-central-dispatch ios swift

18
推荐指数
5
解决办法
6678
查看次数

Block_release在后台线程上释放UI对象

WWDC 2010"Blocks and Grand Central Dispatch"演讲中提出的模式之一是使用嵌套的dispatch_async调用在后台线程上执行耗时的任务,然后在任务完成后更新主线程上的UI

dispatch_async(backgroundQueue, ^{
    // do something time consuming in background
    NSArray *results = ComputeBigKnarlyThingThatWouldBlockForAWhile();

    // use results on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        [myViewController UpdateUiWithResults:results];
    });
});
Run Code Online (Sandbox Code Playgroud)

由于"myViewController"正在块中使用,它会自动获得"保留",并在清除块时稍后获得"释放".

如果块的'release'调用是最终的释放调用(例如,用户在后台任务运行时导航远离视图),则调用myViewController dealloc方法 - 但是它在后台线程上调用!!

UIKit对象不喜欢在主线程之外取消分配.在我的例子中,UIWebView抛出异常.

这个WWDC如何呈现模式 - 特别提到避免UI锁定的最佳新方法 - 是如此有缺陷?我错过了什么吗?

grand-central-dispatch ios objective-c-blocks

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

使用dispatch_get_main_queue()是否意味着我的代码将在主线程上?

以下代码是否在主线程上运行?"主队列"是指主线程吗?

dispatch_async(dispatch_get_main_queue(),
^{
   // Some code
});
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch dispatch-async

17
推荐指数
3
解决办法
3万
查看次数

主队列上的dispatch_async块永远不会被占用

我有一个应用程序,它使用一个连接队列来处理后台线程上的连接.每个连接发送一个JSON帖子,然后当它收到成功时,将一些对象保存到coredata中.

一旦所有连接完成,我调用dispatch_async主线程来调用finished方法.

但是,在非常特定的数据发送/保存条件下,我注意到dispatch_async主线程的块永远不会被调用,应用程序屏幕冻结,所有执行停止,应用程序处于空闲状态并冻结屏幕.根据xcode的处理能力为0%.

这是块失败的方法.

- (void)connectionDidComplete
{
    _completeConnections++;

    _syncProgress = (float)_completeConnections / (float)_totalConnections;

    dispatch_async(mainQueue, ^(void) {
        [[NSNotificationCenter defaultCenter] postNotificationName:SyncQueueDidUpdateNotification object:nil];
    }); <-- this dispatch works

    if (_completeConnections == _totalConnections)
    {
        // clear unsynced data
        NSArray *syncedObjects = [SyncObject completedSyncObjects];

        if (syncedObjects.count > 0)
        {
            for (SyncObject *syncObject in syncedObjects)
            {
                [syncObject delete];
            }
        }

        //this method saves the current context, then merges this context with the main context right after
        [[VS_CoreDataManager sharedManager] saveManagedObjectContextAndWait:managedObjectContext];

        // …
Run Code Online (Sandbox Code Playgroud)

xcode multithreading objective-c grand-central-dispatch ios

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

如何将代码块分派到iOS中的同一个线程?

问题的主要方面:它是关于iOS的.我可以以某种方式调度代码块,他们将(a)在后台运行和(b)在同一个线程上运行吗?我想在后台运行一些耗时的操作,但这些操作必须在同一个线程上运行,因为它们涉及资源,不能在线程之间共享.

进一步的技术细节,如果需要:它是关于实现Apache Cordova的sqlite插件,Apache Cordova是移动平台上HTML5应用程序的框架.这个插件应该是Cordova的插件API 的WebSQL实现.(这意味着,不可能将整个事务包装在单个块中,这可以使一切变得更容易.)

以下是Cordova文档中的一些代码:

- (void)myPluginMethod:(CDVInvokedUrlCommand*)command
{
    // Check command.arguments here.
    [self.commandDelegate runInBackground:^{
        NSString* payload = nil;
        // Some blocking logic...
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
        // The sendPluginResult method is thread-safe.
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }];
}
Run Code Online (Sandbox Code Playgroud)

但据我所知,无法保证那些调度的代码块(请参阅runInBackground)将在同一个线程上运行.

sqlite asynchronous thread-safety grand-central-dispatch ios

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

Swift 3 beta 5中DispatchQueue的AutoreleaseFrequency

在Xcode 8 beta 5中,初始化程序DispatchQueue已更改为接受qos(服务质量),属性和自动释放频率的单独参数.虽然我将代码转换为使用新的初始化程序时没有任何问题,但我不确定某些属性的含义,特别是自动释放频率.

例如,在Xcode 8 beta 3和Swift 3中,我能够创建一个序列DispatchQueue:

let serialQueue = DispatchQueue(label: "Concurrent Map", attributes: [.serial, .qosBackground], target: nil)
Run Code Online (Sandbox Code Playgroud)

在Xcode 8 beta 5和Swift 3中:

let serialQueue = DispatchQueue(label: "Concurrent Map", qos: .background, attributes: [], autoreleaseFrequency: .inherit, target: nil)
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 在新的DispatchQueue.Attributes中,.serial不再是成员.这是否意味着缺少.concurrent会创建一个串行队列.我在Swift Playgrounds做的初步测试似乎证实了这一点.其他人可以确认吗?
  • 我看到DispatchQueue.AutoreleaseFrequency是一个带有.inherit,.never和.workItem的新类型.这些是什么意思?我做了一些关于GCD和自动释放的研究,但我不太熟悉自动释放池的概念.

grand-central-dispatch swift swift3 xcode8

17
推荐指数
2
解决办法
4440
查看次数

GCD - 用于更新UIImageView的主要vs后台线程

我是GCD的新手,并阻止我进入它.

背景:我正在使用ALAssetsLibrary处理UIScrollView的延迟加载例程.当我的UIScrollView加载时,我用aspectRatioThumbnails我的ALAssets 填充它,然后当用户滚动时,我调用下面的例程来加载fullScreenImage当前正在显示的ALAsset.它似乎工作.

(如果有人有更好的延迟加载例程,请发表评论.我看过我能找到的所有内容以及WWDC视频,但他们似乎更多地处理平铺或者比我需要的更复杂)

我的问题:我使用后台线程来处理加载fullScreenImage,当完成后我使用主线程将其应用于UIImageView.我需要使用主线程吗?我已经看到所有UIKit更新都需要在主线程上发生,但我不确定这是否适用于UIImageView.我认为它确实如此,因为它是一个屏幕元素,但后来我才意识到我根本就不知道.

- (void)loadFullSizeImageByIndex:(int)index
{
    int arrayIndex = index;
    int tagNumber = index+1;
    ALAsset *asset = [self.assetsArray objectAtIndex:arrayIndex];

    __weak typeof(self) weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage];

        if ([weakSelf.scrollView viewWithTag:tagNumber] != nil){

            dispatch_async(dispatch_get_main_queue(), ^{

                if ([weakSelf.scrollView viewWithTag:tagNumber]!= nil){
                    UIImageView * tmpImageView = (UIImageView*)[weakSelf.scrollView viewWithTag:tagNumber];
                    tmpImageView.image = tmpImage;
                }
            });
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch ios

16
推荐指数
1
解决办法
2万
查看次数