Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.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
Iphone 从';这不是主线吗?_Iphone_Cocoa_Cocoa Touch_Multithreading - Fatal编程技术网

Iphone 从';这不是主线吗?

Iphone 从';这不是主线吗?,iphone,cocoa,cocoa-touch,multithreading,Iphone,Cocoa,Cocoa Touch,Multithreading,我的想法是让一个视图在幕后计算时显示给用户。这是一个高度为30px的视图,包含一个UIActivityIndicatorView和一个UILabel,显示当前正在计算的内容 我试图通过使用具有以下方法的ActivityHandler来实现它: - (void)newActivityStarted{ [self performSelectorOnMainThread:@selector(showActivityViewer) withObject:nil waitUntilDone:NO]

我的想法是让一个视图在幕后计算时显示给用户。这是一个高度为30px的视图,包含一个UIActivityIndicatorView和一个UILabel,显示当前正在计算的内容

我试图通过使用具有以下方法的ActivityHandler来实现它:

- (void)newActivityStarted{
    [self performSelectorOnMainThread:@selector(showActivityViewer) withObject:nil waitUntilDone:NO];
}

- (void)activityStopped{
    [self performSelectorOnMainThread:@selector(hideActivityViewer) withObject:nil waitUntilDone:NO];
}

- (void)changeInfoText:(NSString*)infoText{
    [activityView.infoLabel performSelectorOnMainThread:@selector(setText:) withObject:infoText waitUntilDone:NO];
}
以下是在主线程上调用的方法:

-(void)hideActivityViewer{
    CGContextRef context = UIGraphicsGetCurrentContext();
    [UIView beginAnimations:nil context:context];

    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    [UIView setAnimationDuration:0.2];
    [UIView setAnimationDelegate: self];
    [UIView setAnimationDidStopSelector:@selector(closeActivityViewer:finished:context:)];
    [activityView setFrame:CGRectMake(320, 10, 320, 30)];

    [UIView commitAnimations];
}

-(void)closeActivityViewer:(NSString*)id finished:(BOOL)finished context:(id)context{

    [activityView removeFromSuperview];
    [activityView release];
    activityView = nil;
}

-(void)showActivityViewer{

    activityView = [[BCActivityView alloc] initWithFrame:CGRectMake(320, 10, 320, 30)];
    [activityView.infoLabel setText:NSLocalizedString(@"WorkInProgressKey",nil)];

    [[(MyAppDelegate*)[[UIApplication sharedApplication] delegate] window] addSubview: activityView];

    CGContextRef context = UIGraphicsGetCurrentContext();
    [UIView beginAnimations:nil context:context];

    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    [UIView setAnimationDuration:0.2];
    [activityView setFrame:CGRectMake(0, 10, 320, 30)];

    [UIView commitAnimations];
}
正在计算一些耗时数据的后台线程调用newActivityStarted、activityStopped和changeInfoText方法

耗时的线程将按如下方式打开:

NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(calculateData) object:nil];
[[[NSOperationQueue new] autorelease] addOperation:operation];
[operation release];
-(void) calculateData{
    [[ActivityIndicatorHandler instance] newActivityStarted];
    [[ActivityIndicatorHandler instance] changeInfoText:NSLocalizedString(@"InitializingForecastKey", nil)];

    //Do something time consuming

    [[ActivityIndicatorHandler instance] activityStopped];
}
计算如下所示:

NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(calculateData) object:nil];
[[[NSOperationQueue new] autorelease] addOperation:operation];
[operation release];
-(void) calculateData{
    [[ActivityIndicatorHandler instance] newActivityStarted];
    [[ActivityIndicatorHandler instance] changeInfoText:NSLocalizedString(@"InitializingForecastKey", nil)];

    //Do something time consuming

    [[ActivityIndicatorHandler instance] activityStopped];
}
其效果是,在完成整个计算后,将显示并隐藏“活动”视图。我希望GUI显示视图,并在后台进行计算时负责用户交互。但是,即使我在计算中有一个断点,在计算线程完成其工作之前,视图将不可用,并且活动视图也不会显示。。。我不知道怎么了


有人有想法吗?

您是否尝试通过执行以下操作来调用计算:

[self performSelectorInBackground:@selector(calculateData) withObject:nil];
在其他方法中,可能是您的应用程序委托,在初始值设定项中设置本地队列:

NSOperaionQueue* aQueue = [[[NSOperationQueue alloc] init] retain];  //release in dealloc
ActivityHandler* myHandler [[[ActivityHandler alloc] init] retain];  //release in dealloc

Have a method to add ops to the queue:

-(void)queueOperation:(NSInvocationOperation*)anOp;
{
    [aQueue addOperation:anOp];
}

-(IBAction*)startCalcs:(id)sender;
{
    [self queueOperation:[myHandler myOperation]];

}

我想你需要考虑PrimeStudioOnMeNothOn:Objist:WaistunLeDe:方法

不需要在OLAC之后保留消息。这只会造成内存泄漏。当然会。我更改了答案,使myHandler成为应用程序代理的ivar,更好地显示我的意图。感谢您提供详细的答案。如果我比较我们的解决方案,唯一的区别似乎是,您的队列由局部变量引用。我将尝试这个解决方案,然后回来告诉我的结果。但是这会改变什么呢?顺便问一下,为什么在alloc/init之后保留队列和处理程序?我试过了,但遗憾的是它没有改变任何东西。这是同样的现象。计算完成后,该视图将出现并立即消失。