Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Objective c 结束在辅助线程中运行的while循环?_Objective C_Multithreading_Cocoa - Fatal编程技术网

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

Objective c 结束在辅助线程中运行的while循环?,objective-c,multithreading,cocoa,Objective C,Multithreading,Cocoa,我有一个应用程序,其中用户输入应用程序应该重复一个操作多少次。用户输入的值将在while循环中获取并使用,while循环将重复用户指定次数的操作。这个过程可能会很长,我想有一个按钮,可以让用户结束这个过程。我已经将repeat进程移动到了一个辅助线程(NSThread),这样用户可以在进程运行时继续与用户界面交互。当用户按下“停止”按钮时,我无法停止重复过程。允许主线程与需要停止在其中运行的while循环的次线程通信的最佳方式是什么?任何帮助都将不胜感激 谢谢 萨姆 这似乎对我不起作用。。。我使

我有一个应用程序,其中用户输入应用程序应该重复一个操作多少次。用户输入的值将在while循环中获取并使用,while循环将重复用户指定次数的操作。这个过程可能会很长,我想有一个按钮,可以让用户结束这个过程。我已经将repeat进程移动到了一个辅助线程(NSThread),这样用户可以在进程运行时继续与用户界面交互。当用户按下“停止”按钮时,我无法停止重复过程。允许主线程与需要停止在其中运行的while循环的次线程通信的最佳方式是什么?任何帮助都将不胜感激

谢谢

萨姆


这似乎对我不起作用。。。我使用@property(atomic,retain)声明了两个原子数。它们都设置为整数值为0。下面是我在次线程中运行的方法中运行的循环:

 int i = 0;

 while (i < timesToRun && [numberOne intValue] == 0) { 
 [self doSomething]; 
 numberOne = numberTwo;
 i++; 
 }'
inti=0;
而(i
我的停止按钮调用一个方法,该方法将numberTwo的整数值更改为“1”。出于某种原因,这并没有停止循环。我做错什么了吗

编辑:谢谢大家的帮助。经过反复试验,我终于找到了解决问题的办法。我只是创建了一个.strings文件,除了文本“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;
    }
NSString*path=[[NSBundle mainBundle]pathForResource:@“strings”类型的“StopFile”;
NSString*theString=[[NSString alloc]initWithContentsOfFile:path];
NSLog(@“字符串:%@”,字符串);
int i;
对于(i=0;i

如果您看到任何可以改进的地方,请告诉我。谢谢。

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


将属性设置为原子将使其成为线程安全的,这样您就可以在一个线程中更改它,并在另一个线程中读取它。

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

使用原子
int
BOOL
属性等简单属性作为终止标记,而不是
NSNumber
。这些不是引用类型,因此不会有内存问题的风险:

@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...
}

看起来可疑。这只复制了指针,并使
numberOne
指向的旧对象无法访问,即,您可能有漏洞。

使用一个
volatile int
而不是两个
NSNumber
对象。编译器可能正在优化
numberOne=numberTwo
,认为它无法运行ot在循环执行期间发生更改,或者类似的情况。

这似乎对我不起作用…我使用@property(atomic,retain)声明了两个原子数。它们都设置为整数值0。下面是我在方法中运行的循环:'int I=0;而(I原子属性不是有效的属性属性。它只是默认属性;您可以指定
非原子属性
或什么都不指定。@Josh:虽然这可能是真的,但它将按照上面的声明编译(至少在Xcode 4.1中)。它清楚地显示了意图,这比简单地省略非原子要好,依我看。@Josh:我删除了它,但如果指定的话,它确实可以编译。我不明白为什么。嗯,我仍然使用4.0.2。我想知道编译器是否有区别;可能他们最近添加了一个
原子
关键字,就像你说的那样,为了让意图更明确。很多最近,很多事情都在发生变化。文件是一个全局的东西,即与全局变量一样糟糕。这实际上是使用线程时要避免的。原子属性不是有效的属性属性;它只是默认属性。您可以编写非原子属性,也可以什么都不写。
numberOne = numberTwo;