[英]iOS App freezing with NSConditionLock
我在某个时刻冻结了应用程序,这是一个比较棘手的问题。 我猜想这与我使用NSConditionLock
。
我有一个可供使用的库,它包含一系列调查问题,但是它的工作方式是直接竞争最后一个问题而不接受答案,因此需要暂停线程并接受来自问题的输入。用户。
我以前没有使用过它,所以如果我实施不正确,也许有人可以帮忙吗? 如果提供的代码不足,请告诉我。
- (void)viewDidLoad
{
[super viewDidLoad];
//INITIALISE CONDITION LOCK WITH CONDITION 0
condition=[[NSConditionLock alloc]initWithCondition: 0];
}
- (IBAction)startPressed:(UIButton*)sender {
if (sender.tag == 1) {
//START BACKGROUND THREAD
surveyThread = [[NSThread alloc] initWithTarget:self selector:@selector(runProjecttest) object:nil];
[surveyThread start];
}
else
{
//DO SOME STUFF AND THEN UNLOCK
[condition unlockWithCondition:1];
}
}
- (void) runProjecttest:(AbstractTask *)rendertask
{
// DO STUFF AND SHOW UI ON MAIN THREAD, THEN LOCK
[self performSelectorOnMainThread:@selector(showUI:) withObject:task waitUntilDone:YES];
[condition lockWhenCondition: 1];
}
编辑:总之,我想要这个Java代码段的Objc等效...
this.runOnUiThread(showUI);
try
{
//SLEEP
Thread.sleep(1000*60*60*24*365*10);
}
catch (InterruptedException e)
{
//WAKE
setResponse(at,showUI);
}
编辑2:应Paul的要求使用ShowUI方法。
[self removePreviousSubViews];
switch ([task getType]) {
case SingleChoiceType:
{
NSLog(@"SingleChoiceType");
isMultipleChoice = NO;
[self addSingleChoiceView:nil];
break;
}
case TextType:
{
NSLog(@"TextType");
self.txtTextType.keyboardType=UIKeyboardTypeDefault;
[self addTextTypeView:nil];
break;
}
...more cases
}
-(void)addTextTypeView:(NSSet *)objects
{
self.txtTextType.text = @"";
CGRect frame = self.txtQuestionType.frame;
// frame.size = [self.txtQuestionType sizeThatFits: CGSizeMake(self.txtQuestionType.frame.size.width, FLT_MAX)];
frame.size.height = [self textViewHeightForAttributedText:self.txtQuestionType.text andWidth:self.txtQuestionType.frame.size.width andTextView:self.txtQuestionType];
self.txtQuestionType.frame=frame;
self.textTypeView.frame = CGRectMake((self.view.frame.size.width - self.textTypeView.frame.size.width)/2, ( self.txtQuestionType.frame.origin.y+self.txtQuestionType.frame.size.height), self.textTypeView.frame.size.width, self.textTypeView.frame.size.height);
[self.view addSubview: self.textTypeView];
}
我同意BryanChen的看法,我认为您可能还有另一个问题。 没有调查库的详细信息,就无法确认,但是假设它是一个UIViewController而不是接受触摸输入以解决一系列问题,很难理解为什么这是一个线程问题-它根本不应该前进无需用户交互。
除此之外,您对NSCondtionLock
的使用也不正确。
本质上, NSConditionLock
具有代表当前“条件”的NSInteger,但只需考虑一个数字即可。 然后,您可以执行两个基本操作-
lockWhenCondition:x
将阻塞当前线程,直到'condition'为'x'并且锁可用为止。 然后它将要求锁定。
unlockWithCondition:y
释放锁定并将条件设置为“ y”
还有一些方法可以设置超时( lockBeforeDate
)并尝试无锁地声明锁定( tryLock
, tryLockWhenCondition
)。
要同步两个线程,通常的模式是
lockWhenCondition:x
该线程可以申请锁定,因为它是x lockWhenCondition:y
该线程将被阻塞,因为锁是x unlockWithCondition:y
这将使线程2可以声明锁定并取消阻塞该线程 您的代码看起来很奇怪,因为您正在if子句中启动线程,但在else子句中解锁。 我本以为你会喜欢-
-(IBAction)startPressed:(UIButton*)sender {
if (sender.tag == 1) {
//START BACKGROUND THREAD
surveyThread = [[NSThread alloc] initWithTarget:self selector:@selector(runProjecttest) object:nil];
[surveyThread start];
[condition:lockWithCondition:1]; // This will block until survey thread completes
[condition:unlockWithCondition:0]; // Unlock and ready for next time
}
}
- (void) runProjecttest:(AbstractTask *)rendertask
{
// DO STUFF AND SHOW UI ON MAIN THREAD, THEN LOCK
[condition lockWhenCondition: 0];
[self performSelectorOnMainThread:@selector(showUI:) withObject:task waitUntilDone:YES];
[condition unlockWithCondition:1];
}
但是这对我来说似乎是造成僵局的秘诀,因为您正在对等待调查线程完成的主线程执行showUI选择器。
这使我们回到了问题, showUI
做什么,为什么它会直接跳到最后呢?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.