Как сохранить значение NSString как массив символов в структуре в Objective-C? - PullRequest
2 голосов
/ 14 июля 2009

У меня проблемы с присвоением значения NSString char * в структуре одноэлементного класса. Ниже приведено упрощение моей проблемы. Мой код использует больше полей в структуре и передает больше NSString s.

Допустим, у меня есть одноэлементный класс "SingletonClass" со структурой (я сделал домашнюю работу с помощью документации Apple и правильно ее реализовал):

struct sampleStruct {
    char *string1;
    //other fields
} struct1;

с помощью этого метода, который устанавливает значение struct1.string1 для строки NSString, которая была передана:

- (void)initStructWithString:(NSString *)inputString {
     //warning: assignment discards qualifiers from pointer target type
     struct1.string1 = [inputString cStringUsingEncoding:NSUTF8StringEncoding];
}

и этот метод, который использует struct1.string1:

- (void)useCharArray {
     //I would obviously be doing something more complex in reality
     printf("This is the char array: %s", struct1.string1);
     //doesn't print the value I assigned to it, but garbage
}

Когда я звоню initStructWithString:(NSString *)inputString из одного класса и пытаюсь вызвать useCharArray из другого класса struct1.string1 - это куча мусора. Во время отладки я подтвердил, что каждый класс получает один и тот же экземпляр этого SingletonClass.

Я все еще изучаю Objective-C, а также C, так что я знаю, что это может быть проблемой с управлением моей памятью. Я знаю, что [NSString cStringUsingEncoding] должно быть присвоено const char *, а не char *, но я не знаю, как еще это сделать, поскольку поле в структуре - char *. Я пробовал другие подходы в initSructWithString, такие как присвоение новому const char * результата [NSString cStringUsingEncoding] и затем копирование его с strlcpy на struct1.string1. Этот подход имел тот же результат.

Как правильно хранить значение NSString в char * в структуре и как я могу гарантировать, что поля в этой структуре сохраняют свое значение, так как SingletonClass используется различными классами?

Ответы [ 3 ]

4 голосов
/ 14 июля 2009

Стоит отметить, что правильное имя метода будет cStringUsingEncoding:; и что эта строка исчезает примерно одновременно с inputString, поэтому результирующая строка должна быть скопирована.

Возможно, стоит также изучить использование UTF8String (удобный метод, который делает то же самое).

1 голос
/ 03 апреля 2011

Пока не могу комментировать, поэтому пишу здесь (после того, как выше ответ на вопрос) ... Просто натолкнулся на это (я понимаю, что это произошло несколько лет спустя) и подумал, что пример может в некоторой степени помочь другим:

Я использую это, чтобы получить имя игрока из игрового центра на iOS, у меня будут проблемы с забавными персонажами и т. Д., Но мой шрифт все равно их не поддерживает. ppName, очевидно, является указателем на указатель на символ, переданный методу, в котором у меня есть этот код.

*ppName = (char *)malloc(strlen([pPlayer.alias UTF8String]));
strcpy(*ppName, [pPlayer.alias UTF8String]);
0 голосов
/ 19 октября 2013

Если вам нужно сохранить NSString в структуре, а затем из этой структуры получить обратно NSString (например, если вам нужно отправить строку другому игроку в многопользовательской игре Game Center), вы можете сделать это следующим образом:

typedef struct {
   char stringToSend[20];
   int stringToSendLength;
} myStruct;

// create a Struct and an NSString
myStruct aStruct;
NSString *stringToConvert = @"stringToConvert";

// convert NSString into char array
for (int i = 0; i < stringToConvert.length; i++) {
    aStruct.stringToSend[i] = [stringToConvert characterAtIndex:i];
}

aStruct.stringToSendLength = stringToConvert.length; // send string length

// store struct into NSData object
NSData *data = [NSData dataWithBytes:&aStruct length:sizeof(myStruct)];

// retrieve data
myStruct *anotherStruct = (myStruct *)[data bytes];

// convert char array into NSString and only keep part required (without some weird random characters)
NSString *receivedString = [[NSString alloc] initWithBytes:anotherStruct->stringToSend length:anotherStruct->stringToSendLength encoding:NSASCIIStringEncoding];
...