Понимание initWithBytes для строки NSString - PullRequest
6 голосов
/ 17 октября 2011

Предполагая, что "someData" является NSMutableData, содержащим несколько байтов данных.

Если я напишу следующее:

NSString *someString = [NSString string];
[someString initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding];

Вторая строка дает мне "нераспознанный селектор, отправленный экземпляру"ошибка

Но если я напишу:

NSString *someString=[[NSString alloc] initWithBytes:[someData mutableBytes] length:[someData length] encoding:NSUTF8StringEncoding];

, то это работает.Есть ли причина, по которой прежний способ не работает?Можно ли это сделать без «alloc» (заранее создавая someString?)

Спасибо.

Ответы [ 2 ]

4 голосов
/ 17 октября 2011

Причина в том, что объект, возвращаемый [NSString string], не отвечает на селектор -initWithBytes:length:encoding:.Это потому, что строки NSString неизменны - их нельзя изменить после создания.Метод -string использует это преимущество и просто дает вам ссылку на постоянную строку (созданную во время компиляции), которая является пустой.

Мало того, что NSString является кластером классов.Это означает, что когда вы запрашиваете NSString, вы можете фактически получить экземпляр одного из его подклассов.Я предполагаю, что вы получаете подкласс с переопределенным -initWithBytes:length:encoding: для создания исключения, потому что нет смысла отправлять метод init в константную строку, созданную во время компиляции.

Во втором случае высоздаем новую строку NSString во время выполнения и затем отправляем ей сообщение инициализации.Это прекрасно.Обратите внимание, что, поскольку это кластер классов, строка, возвращаемая методом init, может отличаться от той, которая была создана -alloc.

.
3 голосов
/ 17 октября 2011

Первый способ создает пустую, автоматически освобожденную строку, которая уже была инициализирована, а затем пытается инициализировать строку во второй раз. Второй способ выделяет память, затем инициализирует ее соответствующим образом. Обратите внимание, что второй способ не выполняет автоматическое восстановление созданной строки, поэтому вызывающая область все еще несет ответственность. Если вы хотите, вы можете обернуть второй способ удобным способом для категории NSString, чтобы получить нечто более похожее на первое:

@interface NSString (stringWithBytes)

+ (NSString*)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding;

@end

@implementation NSString (stringWithBytes)

+ (NSString*)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding {
    NSString * aString = [[NSString alloc] initWithBytes:bytes length:length encoding:encoding];
    return [aString autorelease];
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...