Reputation: 605
I've to run many packages but also some method (70 methods + 40 packages), and I am building _myArray based on what user have selected in the app interface. This is because I can not know what that user will select before press the "start" button, and the app requires that all things follow a predetermined order (_myArray was sorted). The app support OSX since 10.7
-(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);
}
}
The code is particularly slow while running a packages (always more than 30)..
Any Ideas on how solve?
Upvotes: 0
Views: 150
Reputation: 326
I am not sure if this will help but Apple's installer binary at /usr/sbin/installer does not install more than one package at a time. So even though you have everything dispatched on a queue the underlying tool that gets invoked serializes it and installs one package at time.
So if you have 30 packages (or .pkgs) the installer tool will spend a lot of time unarchiving it and installing it.
I don't think you can get around it without writing your own version of the "installer" tool that does what you want.
Upvotes: 1