[英]NSData dataWithBytesNoCopy from NSInputStream
我正在将图像数据从文件转码为base64编码的字符串,然后在使用NSStream读取文件时又转回字节。 我想我快要到了,但是在转换过程中,我经常在不同地方遇到EXC_BAD_ACCESS。
我对NSStream和缓冲区世界还很陌生,所以如果我在这里采用绝对错误的方法,请随时告诉我。
到目前为止,这是我得到的:
// Copy the bytes from our file input stream buffer
void *base64buffer = malloc(self.buffer[self.bufferOffset]);
// Convert the bytes to NSData for the base64 encode
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];
// Convert our NSData into a base64 encoded string
NSString *base64EncodedData = [dataToEncode base64EncodedString];
// Convert our base64 encoded string back into NSData
NSData *encodedData = [base64EncodedData dataUsingEncoding:NSUTF8StringEncoding];
// Write the bytes to our output stream
bytesWritten = [self.producerStream write:[encodedData bytes] maxLength:[encodedData length]];
// Clean up
dataToEncode = nil;
base64EncodedData = nil;
encodedData = nil;
free(base64buffer);
这里有几个问题:
// Copy the bytes from our file input stream buffer
void *base64buffer = malloc(self.buffer[self.bufferOffset]);
这并没有按照您的评论所说的做。 您刚刚完成的操作在self.buffer[self.bufferOffset]
处分配了与size_t相同大小的缓冲区(4字节或8字节无符号整数),基本上,您尝试分配实质上是随机大小的缓冲区。 如果大小太大,则会返回NULL,这可能是导致崩溃的原因。
// Convert the bytes to NSData for the base64 encode
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];
这并没有按照您的想法做。 sizeof(base64buffer)
是4还是8,具体取决于您是以32位还是64位模式进行编译。 它是指针的大小,而不是缓冲区的大小。
free(base64buffer);
创建初始NSData时,对“ freeWhenDone”说“是”。 这意味着NSData拥有base64buffer
所有权, base64buffer
在释放后尝试释放它。 由于您已经释放了它,因此该操作将以无法预测的讨厌方式失败。
我们该如何解决? 尝试这样的事情:
size_t bufferLengthInBytes = .... // you'll need to figure out how to get this
// Next, instead of mallocing my own buffer for the data, I'll let the runtime do it for me.
// I'm assuming that self.buffer is a pointer to the bytes you want to copy.
NSData* dataToEncode = [NSData dataWithBytes: self.buffer length:bufferLengthInBytes];
// I'm not sure where the method base64EncodedString comes from. I assume you have a category to do this.
NSString *base64EncodedString = [dataToEncode base64EncodedString];
该方法的其余部分应该相同,除了您没有缓冲区可以释放为止(事实上,您实际上没有使用过)。
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];
释放dataToEncode时,此行将执行free(base64buffer),因为freeWhenDone: YES 。 因此,您将释放相同的内存空间两次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.