线程从NSString中提取子字符串

时间:2013-07-19 08:24:43

标签: iphone objective-c ios6 nsstring nsthread

我正在使用适用于iOS的RedPark串行电缆进行一些工作。这是一种允许iOS设备与其他设备(如微控制器)之间进行串行通信的电缆。

RedPark SDK附带了一种方法,用于读取串行线路上可用的字节数。只要电缆接收到信息,就会调用此方法。

(void)readDataBytes(UInt32 bytes) {
   NSString *s = [[NSString alloc] initWith...bytes];
   NSString *editedString = [self extractSubStringMethod:s];
   [myArray addObject:editedString];
}

微控制器正在以下列格式发送信息

<msg>xxxxxxxxxxxxx</msg>

我希望能够从消息中提取x(作为NSString获取)。目前我正在使用NSRange提取位置4(第一个x)之后和最后一个“&lt; / msg&gt;”之后的所有内容我不相信它有效,并且想知道还有其他想法吗?

最后,我有一个与此同时运行的NSThread,我将消息添加到NSMutableArray中。所以我想要的是,NSThread在从电缆收到消息时操纵/显示消息信息。我有类似以下的内容

//Thread method, 
while([myArray count] > 0) //Don't believe this is neccesary but its in anyway
{
  for(int i = 0; i < [myArray count]; i++){
    NSString *string = [myArray objectAt(i)];
    [self displayString:string];
    [myArray removeObjectAt(i);
    }
}

我相信它正在崩溃... [self displayString:string]只是设置一个标签的值,比如

-(void)displayString(NSString *string) {
 label.text = [string charAt(1)];
}

上面的代码只是来自记忆,因为我已经将Mac放在家中,而且我正在工作。 任何建议/帮助将不胜感激

3 个答案:

答案 0 :(得分:1)

而不是

while([myArray count] > 0) //Don't believe this is neccesary but its in anyway
{
  for(int i = 0; i < [myArray count]; i++){
    NSString *string = [myArray objectAt(i)];
    [self displayString:string];
    [myArray removeObjectAt(i);
    }
}

尝试这样:

while ([myArray count] > 0)
{
    [self displayString: myArray[0]];        
    [myArray removeObjectAtIndex: 0];
}

答案 1 :(得分:1)

要解决您的第一个问题,[string substringWithRange:NSMakeRange(5, string.length - 6)]应该足够了,应该没有任何问题。您可以使用NSRegularExpression来匹配标记内的内容,但这对于这样一个简单的任务来说是过度的(并且会有性能损失)。

其次,UIKit方法只能从主线程中调用(参见documentation):

  

注意:在大多数情况下,UIKit类只能从应用程序的主线程中使用。对于从UIResponder派生的类或者涉及以任何方式操纵应用程序的用户界面的类,尤其如此。

您似乎在不同的主题中设置标签的文本。这就是导致崩溃的原因。您需要像这样调用displayString:方法:

[self performSelectorOnMainThread:@selector(displayString:) withObject:string waitUntilDone:YES];

这将在主线程而不是后台线程上执行该方法。

答案 2 :(得分:1)

  1. 您不得在辅助线程上更新UI。
  2. 可变类不是线程安全的。

    while([myArray count]){ NSString * string = [myArray objectAt(0)]; [self performSelectorOnMainThread:@selector(displayString :) withObject:string waitUntilDone:NO]; [myArray removeObjectAt(0); }