在我目前的项目中,我遇到了以下问题:
应用程序需要与我的服务器交换数据,这些数据存储在iPhone上的NSMutableArray中。该数组包含NSString,NSData和CGPoint值。 现在,我认为最简单的方法是将数组转换为格式正确的字符串,将其发送到我的服务器并将其存储在一些mySQL数据库中。此时我想从我的服务器请求表示我的数组内容的字符串,然后实际将其转换回NSMutablArray。
到目前为止,我尝试过这样的事情:
NSString *myArrayString = [myArray description];
现在我将此字符串发送到我的服务器并将其存储在mySQL数据库中。那部分效果很好。
但是,当我从服务器收到字符串时,我无法将其转换回NSMutableArray。
是否有方法可以轻松地将数组描述转换回数组?不幸的是到目前为止我找不到任何东西。 也许我从一开始就“序列化”数组的方式是错误的,并且有一种更聪明的方法可以做到这一点。
任何帮助表示赞赏。提前谢谢。
答案 0 :(得分:4)
不要使用description
,因为这是为了让它变成人类可读的“漂亮”格式。你想要的是对象的数据转储。
您可能想要做的是利用NSArray
执行NSCoding
以从中获取原始字节数组的事实 - NSData
。 (这是您提到的序列化。)然后,您可以将原始字节传输到服务器,使用zip压缩,或者对base-64中的字节进行编码,以通过HTTP发送查询字符串。要恢复数组,您只需撤消该过程。
Stack Overflow上有很多现有的问题和答案可以帮助您解决这个问题。这是一对夫妇:
答案 1 :(得分:0)
好吧,我想我离得更近了。但是,我还没到那里,因为在将数据转换回新数组时遇到了一些“EXC_BAD_ACCESS”。
让我与您分享一些代码。以下是应该将数组转换为NSData,将NSData转换为base64,反之亦然。
@interface NSArray (dataConversion)
+ (NSArray*) arrayWithData:(NSData*) data;
- (NSData*) convertToData;
@end
@implementation NSArray (dataConversion)
- (NSData*) convertToData {
unsigned n= [self count];
NSMutableData* data = [NSMutableData dataWithLength: sizeof(unsigned)+
sizeof(id) *n];
unsigned* p = [data mutableBytes];
*p++= n;
[self getObjects:(void*)p];
return data;
}
+ (NSArray*) arrayWithData:(NSData*) data {
unsigned* p = (unsigned*)[data bytes];
unsigned n = *p++;
return [NSArray arrayWithObjects:(id*)p count:n];
}
@end
@interface NSData (MBBase64)
+ (id)dataWithBase64EncodedString:(NSString *)string; // Padding '=' characters are optional. Whitespace is ignored.
- (NSString *)base64Encoding;
@end
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@implementation NSData (MBBase64)
+ (id)dataWithBase64EncodedString:(NSString *)string;
{
if (string == nil)
[NSException raise:NSInvalidArgumentException format:nil];
if ([string length] == 0)
return [NSData data];
static char *decodingTable = NULL;
if (decodingTable == NULL)
{
decodingTable = malloc(256);
if (decodingTable == NULL)
return nil;
memset(decodingTable, CHAR_MAX, 256);
NSUInteger i;
for (i = 0; i < 64; i++)
decodingTable[(short)encodingTable[i]] = i;
}
const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL) // Not an ASCII string!
return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (YES)
{
char buffer[4];
short bufferLength;
for (bufferLength = 0; bufferLength < 4; i++)
{
if (characters[i] == '\0')
break;
if (isspace(characters[i]) || characters[i] == '=')
continue;
buffer[bufferLength] = decodingTable[(short)characters[i]];
if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
{
free(bytes);
return nil;
}
}
if (bufferLength == 0)
break;
if (bufferLength == 1) // At least two characters are needed to produce one byte!
{
free(bytes);
return nil;
}
// Decode the characters in the buffer to bytes.
bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
if (bufferLength > 2)
bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
if (bufferLength > 3)
bytes[length++] = (buffer[2] << 6) | buffer[3];
}
realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}
- (NSString *)base64Encoding;
{
if ([self length] == 0)
return @"";
char *characters = malloc((([self length] + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [self length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [self length])
buffer[bufferLength++] = ((char *)[self bytes])[i++];
// Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease];
}
@end
现在,我这样使用它:
NSData *messageData = [[NSArray arrayWithArray:myNSMutableArray] convertToData];
NSString *messageData = [messageData base64Encoding];
messageData是我现在发送到服务器的字符串。这很好。
现在反过来了:
NSData *arrayData = [NSData dataWithBase64EncodedString:serverResponseString]; //serverResponseString is the string returned from my server upon request
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:[NSArray arrayWithData:arrayData]]; //here it crashes and points to: "return [NSArray arrayWithObjects:(id*)p count:n];"
我要么在这里丢失一些东西,要么完全偏离轨道。任何帮助赞赏。感谢。