Данные NSDataWithBytesNoCopy и writeToFile - PullRequest
0 голосов
/ 23 июня 2011

У меня есть метод категории, который делает что-то вроде этого:

@implementation NSData (additions)
- (id)someFunc {

char *buffer = malloc(255);
NSUInteger length = 0;
while (true) {
    // . . . fill buffer[length++];
}

realloc(buffer, length);
return [NSData dataWithBytesNoCopy:buffer length:length freeWhenDone:NO];
}

Затем я пытаюсь записать возвращенные данные (ну, назовите это NSData * fileData):

NSError *error;
NSData fileData = [NSData someFunc];
[fileData writeToFile:somePath options:NSDataWritingAtomic error:&error];

Я получаю сообщение об ошибке:

Ошибка домена = NSCocoaErrorDomain Code = 512 "Операция не может быть завершена. (Ошибка 512 какао.)" UserInfo = 0x20deffd0 {NSFilePath = / Users / user / Library /Поддержка приложений / iPhone Simulator / 4.3 / Приложения / 4C315580-153D-4FA7-9474-E17B58832515 / Библиотека / Caches / file.pdf, NSUnderlyingError = 0x20de1fe0 "Операция не может быть завершена. Неверный адрес"}

Путь существует и действителен.Я думаю, что проблема заключается в том, что возвращаемое NSData - просто легкая оболочка вокруг массива, выделенного с помощью malloc, и что writeToFile не знает, как с этим справиться.Кто-нибудь видит, что я делаю не так?

Ответы [ 2 ]

1 голос
/ 24 июня 2011

Когда вы вызываете realloc, вы должны сохранить возвращенный указатель, поскольку realloc может выделить новый буфер и скопировать содержимое старого местоположения в это новое местоположение.После этого старое местоположение будет free d и, таким образом, будет недействительным.Другой malloc вызов может перезаписать это старое местоположение.

Так что вам нужно сделать:

buffer = realloc(buffer, length);
0 голосов
/ 23 июня 2011

Этот код не имеет никакого смысла.

  • показать код, который вы используете для заполнения буфера

  • у вас есть malloc (), почему вы используете realloc () после цикла? Это пустая трата циклов, и если целью было расширение буфера, если входные данные были слишком длинными, они не будут работать так, как написано.

  • вы должны проверить возвращаемое значение из writeToFile:options:error:, чтобы узнать, есть ли ошибка; Вы не можете проверить ошибку напрямую.

  • также не прикрепляйте такую ​​категорию к существующему классу. В целом, это свидетельствует об архитектуре, которая является хрупкой и плохо наслоенной. Если вы идете по этому пути, по крайней мере, перед вашим методом добавьте что-то уникальное.

Не ясно, почему возникла эта конкретная ошибка. Этот путь кажется немного странным, как вы его генерируете?

...