Как объединить 3 переменные NSData

Как объединить 3 NSData переменные?

NSData *iv;
NSData *salt;
NSData *encryptedData;

Мне нужно объединить их с одной переменной. Может ли кто-нибудь показать мне способ.

Ответы

Ответ 1

используйте объект NSMutableData и метод -(void)appendData:(NSData *)otherData

Отредактировано для добавления примера:

NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:iv];
[concatenatedData appendData:salt];
[concatenatedData appendData:encryptedData];
// and now you have all of the data in the single variable "concatenatedData"

Ответ 2

Для тех, кто кодирует iOS5 и позже. Я бы хотел показать какую-то реальную конкатенацию. Почему эти ответы недостаточно хороши? Потому что они связаны с дополнительным использованием памяти для скопированных данных. Давайте посмотрим на ответ:

NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:iv];
[concatenatedData appendData:salt];
[concatenatedData appendData:encryptedData];

здесь у нас выделена память для iv, salt и encryptedData также каждый раз, когда мы добавляем один из них в нашу изменчивую конкатенацию, мы, очевидно, снова копируем его в изменяемые данные. Нужны ли нам дополнительные расходы при работе с большими данными? Меня нет.

Существует способ избежать этого ненужного расхода памяти - dispatch_data Я не буду объяснять, как это работает, вы можете сделать это, если хотите. Я просто даю вам код, который работает:

NSData *iv = [@"some data" dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [@"even more data" dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [@"and one more" dataUsingEncoding:NSUTF8StringEncoding];
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_data_t dispatch_data_iv = dispatch_data_create([iv bytes], [iv length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
dispatch_data_t dispatch_data_salt = dispatch_data_create([salt bytes], [salt length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
dispatch_data_t dispatch_data_encrypted = dispatch_data_create([encryptedData bytes], [encryptedData length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
iv = nil; salt = nil; encryptedData = nil; // free all parts, we dont need it anymore
dispatch_data_t dispatch_data_concat = dispatch_data_create_concat( dispatch_data_create_concat(dispatch_data_iv, dispatch_data_salt), dispatch_data_encrypted);
NSData *concatenatedNSData = DataFromDispatchData(dispatch_data_concat);

// lets check now if the concatenation works properly
NSString *stringFromConcatenatedNSData = [[NSString alloc]initWithData:concatenatedNSData encoding:NSUTF8StringEncoding];
NSLog(@"%@",stringFromConcatenatedNSData); 

не забывайте о вспомогательном преобразователе

NSData *DataFromDispatchData(dispatch_data_t data)
{
    NSMutableData *result = [NSMutableData dataWithCapacity: dispatch_data_get_size(data)];
    dispatch_data_apply(data, ^(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
        [result appendBytes:buffer length:size];
        return (_Bool)true;
    });
    return result;
}

Ответ 3

Вы можете использовать метод NSMutableData -appendData:

NSMutableData *result = [NSMutableData data];

[result appendData:iv];
[result appendData:salt];
[result appendData:encryptedData];

// result now has what you need.

Это связано с издержками использования изменяемых данных, которые могут быть медленнее и использовать больше памяти, поэтому используйте их с осторожностью. Вообще говоря, вы не хотите, чтобы большие NSData плавали вокруг.

Ответ 4

Сначала создайте два NSObjects и используйте этот метод

-(void)appendData:(NSData *)otherData  

и поместите один NSData позже с третьим NSData, также связанным с тем же методом.