结束在辅助线程中运行的while循环?

时间:2011-08-19 20:35:49

标签: objective-c multithreading cocoa

我有一个应用程序,用户输入应用程序重复操作的次数。用户输入的值在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;
    }

如果您发现任何可以改进的内容,请与我们联系。感谢。

4 个答案:

答案 0 :(得分:5)

您可以在执行while循环的对象上添加原子属性,并在循环的每次迭代中检查该属性。

使属性为atomic将使其成为线程安全的,以便您可以在一个线程中更改它,并在另一个线程中读取它。

答案 1 :(得分:0)

这里最好的选择是在while循环的每次迭代中检查一个易失性原子变量。然后,您的“停止线程”可以将其设置为停止值。然后,您的“循环线程”将检查此变量,并在设置时停止。

答案 2 :(得分:0)

使用简单的原子NSNumberint属性作为终止标记,而不是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,认为它在执行循环期间无法改变,或类似的东西。