2

I'm doing some work using the RedPark Serial Cable for iOS. This is a cable that allows serial communication between an iOS device and another device like a microcontroller.

There is a method that comes with the RedPark SDK that reads the bytes available on the Serial Line. This method is called anytime the cable receives informatino.

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

The microcontroller is sending the information in the following format

<msg>xxxxxxxxxxxxx</msg>

I want to be able to extract the x's from the message (which is taken in as an NSString). At the moment I'm using NSRange to extract everything after position 4 (the first x) and before the final "< /msg>" I'm not convinced it works and was wondering is there any other ideas?

Finally, I have an NSThread which is running alongside this, I have the messages being added to an NSMutableArray. So what I want is, the NSThread to be manipulating/displaying the message information when there is a message received from the cable. I have something like the following

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

I believe it's crashing around the above... [self displayString:string] just sets the value of a label, something like

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

The code above is just from memory as I've left my Mac at home and I'm in work. Any suggestions/help would be appreciated

Denny
  • 285
  • 1
  • 2
  • 16
David Evans
  • 213
  • 1
  • 2
  • 12

3 Answers3

1

Instead of

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

try like this:

while ([myArray count] > 0)
{
    [self displayString: myArray[0]];        
    [myArray removeObjectAtIndex: 0];
}
stosha
  • 2,108
  • 2
  • 27
  • 29
1

To address your first concern, [string substringWithRange:NSMakeRange(5, string.length - 6)] should be sufficient and should work without any issues. You could use an NSRegularExpression to match the content inside the tags, but that would be overkill for such a simple task (and would have a performance hit).

Secondly, UIKit methods must only be called from the main thread (see documentation):

Note: For the most part, UIKit classes should be used only from an application’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your application’s user interface in any way.

You appear to be setting the text of a label in a different thread. This is what is causing the crash. You need to call your displayString: method like this:

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

This will execute the method on the main thread instead of on a background thread.

Greg
  • 9,068
  • 6
  • 49
  • 91
1
  1. You must not update UI on secondary thread.
  2. Mutable classes are not thread safe.

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

Parag Bafna
  • 22,812
  • 8
  • 71
  • 144