List NSString characters with a pointer

How can I list an NSString by pulling every unichar from it? I can use characterAtIndex, but it is slower than running with incremental unichar *. I did not see anything in the Apple documentation that did not require copying the string to the second buffer.

Something like this would be ideal:

for (unichar c in string) { ... }

or

unichar* ptr = (unichar*)string;
+5
source share
5 answers

You can speed it up -characterAtIndex:by first converting it to an IMP form:

NSString *str = @"This is a test";

NSUInteger len = [str length]; // only calling [str length] once speeds up the process as well
SEL sel = @selector(characterAtIndex:);

// using typeof to save my fingers from typing more
unichar (*charAtIdx)(id, SEL, NSUInteger) = (typeof(charAtIdx)) [str methodForSelector:sel];

for (int i = 0; i < len; i++) {
    unichar c = charAtIdx(str, sel, i);
    // do something with C
    NSLog(@"%C", c);
}  

EDIT: It looks like the CFStringLink contains the following method:

const UniChar *CFStringGetCharactersPtr(CFStringRef theString);

This means that you can do the following:

const unichar *chars = CFStringGetCharactersPtr((__bridge CFStringRef) theString);

while (*chars)
{
    // do something with *chars
    chars++;
}

If you do not want to allocate memory for copying the buffer, this is the way to go.

+11
source

- . , NSString , . - getCharacters:range:.

NSUInteger i, length = [string length];
unichar *buffer = malloc(sizeof(unichar) * length);
NSRange range = {0,length};
[string getCharacters:buffer range:range];
for(i = 0; i < length; ++i) {
    unichar c = buffer[i];
}

, ( , ).

+4

, getCharacters:range: , ughoavgfhw . , CFStringGetCharactersPtr null, malloc . NSString , , .

-(void)enumerateCharactersWithBlock:(void (^)(unichar, NSUInteger, BOOL *))block
{
    const NSInteger bufferSize = 16;
    const NSInteger length = [self length];
    unichar buffer[bufferSize];
    NSInteger bufferLoops = (length - 1) / bufferSize + 1;
    BOOL stop = NO;
    for (int i = 0; i < bufferLoops; i++) {
        NSInteger bufferOffset = i * bufferSize;
        NSInteger charsInBuffer = MIN(length - bufferOffset, bufferSize);
        [self getCharacters:buffer range:NSMakeRange(bufferOffset, charsInBuffer)];
        for (int j = 0; j < charsInBuffer; j++) {
            block(buffer[j], j + bufferOffset, &stop);
            if (stop) {
                return;
            }
        }
    }
}
+1

:

char *s = [string UTF8String];
for (char *t = s; *t; t++)
  /* use as */ *t;

[Edit] Unicode, , length characterAtIndex. :

NSString - length characterAtIndex: - . length Unicode . characterAtIndex: , 0.

, :

  for (int index = 0; index < string.length; index++)
    { 
      unichar c = [string characterAtIndex: index];
      /* ... */
    }

[edit 2]

, , NSString " " CFString, , , Objective-C, C- . CFStringGetCharacterAtIndex

0

I do not think you can do this. NSStringIt is an abstract interface for many classes that do not give any guarantees regarding the internal memory of character data, so it is quite possible that there is no character array for receiving a pointer.

If none of the options mentioned in your question are suitable for your application, I would recommend either creating your own string class for this purpose, or using raw unichar malloc arrays rather than string objects.

0
source

All Articles