Каков наилучший подход к преобразованию неизменяемых объектов в изменяемые объекты (рекурсивный)?

В частности, эта проблема пришла ко мне, когда я делаю запрос с AFNeworking с JSONkit и получаю (id) JSON с несколькими массивами и словарями вложенными.

Если я не хочу изменять данные, у меня нет проблем:

self.myNSArray = [JSON objectForKey:@"result"];

Но если я хочу изменить данные, я должен их сохранить в изменяемой переменной:

self.myNSMutableArray = [[JSON objectForKey:@"result"] mutableCopy];

Последний не конвертирует вложенные массивы или словари в изменяемые данные; он работает только для первого уровня.

Единственный способ, который я нашел, - это ссылка рекурсивные изменяемые объекты; но я не знаю, есть ли лучший способ решить эту проблему.

Спасибо заранее.

Ответ 1

Вы можете использовать функцию CoreFoundation CFPropertyListCreateDeepCopy с опцией изменчивости kCFPropertyListMutableContainersAndLeaves:

NSArray *immutableArray = [JSON objectForKey:@"result"];
self.myMutableArray = [(NSMutableArray *)CFPropertyListCreateDeepCopy(NULL, immutableArray, kCFPropertyListMutableContainersAndLeaves) autorelease];

Ответ 2

В ARC:

CFBridgingRelease(CFPropertyListCreateDeepCopy(NULL, (__bridge CFPropertyListRef)(immutableArray), kCFPropertyListMutableContainersAndLeaves))

действительно работал. благодаря brainjam.

Ответ 3

Убедитесь, что вы берете значения null в строке ответа, иначе оно вернет вам нуль, что приведет к ужасным результатам.

(Например, попробуйте мутатирующий ответ от http://www.json-generator.com/api/json/get/bQVoMjeJOW?indent=1)

Просто подставьте строку ниже при преобразовании ответа API на объект JSON.

responseString=[responseString stringByReplacingOccurrencesOfString:@"\":null" withString:@"\":\"\""];//To Handle Null Characters

//Search for below line in your parsing library and paste above code
data = [responseString dataUsingEncoding:NSUTF8StringEncoding];

Таким образом, в вашем объекте JSON не будет никаких нулевых символов, поэтому нет проблем с использованием CFPropertyListCreateDeepCopy.

Ура!!