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

原文 标签 objective-c multithreading cocoa

End a while loop that is running in a secondary thread?

I have an application where the user inputs how many times the application should repeat an action. The user inputed value is taken and used in a while loop that repeats the action the user specified amount of times. The process can be very long and I would like to have a button that would allow the user to end the process. I have moved the repeat process to a secondary thread (NSThread) so that the user can continue to interact with the user interface while the process is running. I'm having trouble stopping the repeat process when the user presses the "Stop" button. What is the best way to allow my main thread to communicate to a secondary thread that it needs to stop a while loop running in it? Any help would be greatly appreciated.

Thanks,

Sam

This didn't seem to work for me... I declared two atomic NSNumbers using @property (atomic, retain). They are both set to have an integer value of 0. Here is my loop that runs in the method run in the secondary thread:

 int i = 0;

 while (i < timesToRun && [numberOne intValue] == 0) { 
 [self doSomething]; 
 numberOne = numberTwo;
 i++; 
 }'

My stop button calls a method that changes the integer value of numberTwo to "1". For some reason this isn't stopping the loop. Am I doing something incorrectly?

EDIT: Thank you all for your help. After quite a bit of trial and error, I finally found a solution to my problem. I simply created a .strings file that is empty except for the text "NO". I set the text to "NO" when the application is loaded. In my new while loop, I check to see if the value of the file has changed using an NSString stringWithContentsOfFile. When I want to end the loop I call a method that writes to the file and changes the value to "YES". Here's my new loop:

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;
    }

Please let me know if you see anything that can be improved. Thanks.

Answer

You can add an atomic property on the object performing the while loop, and check the property with each iteration of the loop.

Making the property atomic will make it thread-safe, so that you can change it in one thread, and read it in another.

翻译

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


如果您有任何可以改进的地方,请告诉我。谢谢。
最佳答案
您可以在执行while循环的对象上添加一个原子属性,并在每次循环迭代时检查该属性。

将属性设为原子将使其成为线程安全的,因此您可以在一个线程中更改它,而在另一个线程中读取它。
相关推荐

iphone - 为什么在此参数中使用for循环

iphone - 在崩溃时调用applicationWillTerminate

iphone - iOS-UITextView不绘制文本吗?

iphone - CGContext设置文本以在生成pdf时证明其正确性

objective-c - 修改NSScroller的长度

objective-c - Objective-C:从集合中获取最高的枚举类型

objective-c - window:willPositionSheet:usingRect不会被调用

objective-c - 最有效的防裂方法

iphone - UIDatePicker突出显示了今天的日期-如何更改该颜色?

objective-c - 将信息从A类传递给B类而不是直接传递给C类是不好的编程设计吗?