使用GCD进行慢速循环

时间:2014-12-17 20:46:32

标签: objective-c macos cocoa

我运行了很多软件包,但也运行了一些方法(70种方法+40个软件包),我根据用户在应用程序界面中选择的内容构建了_myArray。 这是因为在按下" start"之前我无法知道用户将选择什么。按钮,应用程序要求所有事情都遵循预定的顺序(_myArray已排序)。该应用程序从10.7开始支持OSX

-(void)package01 {
}

-(void)package02 {
}

.....

-(void)package40 {

    // also tried with NSTask, but is slow exactly as NSAppleScript (so guess that this is not the problem)

    NSString* package = [_pathToPkg stringByAppendingPathComponent:@"40.pkg"];
    NSAppleScript* runpkg;
    NSString *command = [NSString stringWithFormat:@"/usr/sbin/installer -pkg %@ -target %@", package, _targetOBJ];

    runpkg = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:
                                                    @"do shell script \"%@\"", command]];

    [runpkg executeAndReturnError: nil];
}

-(void)oneOfMyMethod {
dispatch_async(_myQueue,
               ^{
                   // some operation
                   dispatch_async(_mymainQueue, ^{/*updating interface here*/});
               });

dispatch_async(_myQueue,
               ^{
                   // more operation
                   dispatch_async(_mymainQueue, ^{/*updating interface here*/});
               });

dispatch_async(_myQueue,
               ^{
                   // ++ operation
                   dispatch_async(_mymainQueue, ^{/*updating interface here*/});
               });


// Here I'm calling the problematic Method:
[self runPackageOrMethod:^(BOOL finished) {
    if(finished){
        [self doOther];
    }
}];

}

// this is pratically the core of the app...
- (void) runPackageOrMethod:(completion) compblock{

    _pathToPkg = @"path/to/the/folder/that/contain/packages";


    dispatch_group_t group = dispatch_group_create();

    @try {
        for (NSString *method in _myArray) {
                    NSArray *descriptions;
                    descriptions = [NSArray arrayWithArray:[METHOD_DESCRIPTION allKeys]]; // Another array that I use to display some info about running pkg or method

                    dispatch_group_async(group,_myQueue, ^ {
                        dispatch_async(_mymainQueue, ^{
                            if ([descriptions containsObject:method] && ![[METHOD_DESCRIPTION objectForKey:method] isEqualToString:@"MUTE"]) {
                                [_displayStore appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n- %@\n", [METHOD_DESCRIPTION objectForKey:method]]  attributes:_dispAttr]];
                                [_display scrollToEndOfDocument:self];
                            }
                        });
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                        dispatch_async(_mymainQueue, ^{[self performSelector:NSSelectorFromString(method)  withObject:nil];});
#pragma clang diagnostic pop
                    });
            }
    }
    @catch (NSException *exception) {
        NSLog(@"ERROR: %@", [exception description]);
    }
    @finally {
        compblock(YES);
    }
}

运行包时(总是超过30个)代码特别慢..

关于如何解决的任何想法?

1 个答案:

答案 0 :(得分:1)

我不确定这是否会有所帮助,但/ usr / sbin / installer中的Apple安装程序二进制文件一次不会安装多个程序包。因此,即使您在队列中调度了所有内容,调用的基础工具也会对其进行序列化并在时间安装一个包。

因此,如果您有30个软件包(或.pkgs),安装程序工具将花费大量时间取消归档并安装它。

我不认为你可以绕过它,而无需编写自己版本的"安装程序"做你想做的工具。