我有一个应用程序,用户输入应用程序重复操作的次数。用户输入的值在while循环中获取并使用,该循环重复用户指定的次数的操作。这个过程可能很长,我希望有一个允许用户结束这个过程的按钮。我已将重复过程移至辅助线程(NSThread),以便用户可以在进程运行时继续与用户界面进行交互。当用户按下“停止”按钮时,我无法停止重复过程。允许我的主线程与辅助线程进行通信的最佳方法是什么,它需要停止在其中运行的while循环?任何帮助将不胜感激。
谢谢,
萨姆
这似乎对我不起作用......我使用@property(atomic,retain)声明了两个原子NSNumber。它们都设置为整数值0.这是我在第二个线程中运行的方法中运行的循环:
int i = 0;
while (i < timesToRun && [numberOne intValue] == 0) {
[self doSomething];
numberOne = numberTwo;
i++;
}'
我的停止按钮调用一个方法,将numberTwo的整数值更改为“1”。由于某种原因,这不是停止循环。我做错了什么吗?
编辑:谢谢大家的帮助。经过相当多的反复试验,我终于找到了解决问题的方法。我只是创建了一个空的.strings文件,除了文本“NO”。加载应用程序时,我将文本设置为“NO”。在我的新while循环中,我使用NSString stringWithContentsOfFile检查文件的值是否已更改。当我想结束循环时,我调用一个写入文件的方法并将值更改为“YES”。这是我的新循环:NSString* path = [[NSBundle mainBundle] pathForResource:@"StopFile" ofType:@"strings"];
NSString *theString = [[NSString alloc] initWithContentsOfFile:path];
NSLog(@"TheString: %@", theString);
int i;
for (i = 0; i < timesToRunScript && theString == [NSString stringWithFormat:@"NO"]; i++) {
[scriptToRun executeAndReturnError:nil];
NSString *theString = [[NSString alloc] initWithContentsOfFile:path];
NSLog(@"string: %@", theString);
if (theString == [NSString stringWithFormat:@"Yes"]) {
break;
}
如果您发现任何可以改进的内容,请与我们联系。感谢。
答案 0 :(得分:5)
您可以在执行while循环的对象上添加原子属性,并在循环的每次迭代中检查该属性。
使属性为atomic将使其成为线程安全的,以便您可以在一个线程中更改它,并在另一个线程中读取它。
答案 1 :(得分:0)
这里最好的选择是在while循环的每次迭代中检查一个易失性原子变量。然后,您的“停止线程”可以将其设置为停止值。然后,您的“循环线程”将检查此变量,并在设置时停止。
答案 2 :(得分:0)
使用简单的原子NSNumber
或int
属性作为终止标记,而不是BOOL
。这些不是引用类型,因此您不会冒任何内存问题的风险:
@property(assign) BOOL terminateASAP;
在你的循环中执行:
for (i = 0; i < timesToRun && !terminateASAP; i++)
{
[self doSomething];
// etc...
// if necessary, e.g. because each iteration is slow,
// add more checks for terminateASAP:
if (terminateASAP)
break;
// more slow code...
}
FWIW,该行
numberOne = numberTwo;
看起来很可疑。那只复制指针,并留下numberOne
指向不可访问的旧对象,即你有泄漏。
答案 3 :(得分:0)
使用单个volatile int
代替两个NSNumber
对象。编译器可能正在优化numberOne = numberTwo
,认为它在执行循环期间无法改变,或类似的东西。