Глубокая копия и мелкая копия - PullRequest
15 голосов
/ 28 марта 2012

Я прочитал ответ на различие между глубокой копией и мелкой копией из поста, В чем разница между глубокой копией и мелкой копией? .Теперь у меня появилось некоторое сомнение, что когда мы сделали поверхностную копию

 newArray = [NSmutableArray arrayWithArray:oldArray];

, новый массив будет указывать на oldArray.(Как на рисунке).Что произойдет, когда я удалю объект из newArray?Как видно из рисунка, он должен удалить тот же элемент из oldArray !!!Кажется, что

newArray = oldArray - это мелкая копия, а newArray = [NSmutableArray arrayWithArray:oldArray]; - глубокая копия.Это правильно?

Ответы [ 4 ]

41 голосов
/ 28 марта 2012

newArary = oldArray не является копией вообще. Вы получите два указателя, указывающих на одну и ту же область памяти.

newArray = [NSMutableArray arrayWithArray:oldArray]; это мелкая копия. В итоге вы получите два разных массива, поэтому если вы удалите или добавите элементы из одного массива, это не повлияет на другой массив. Тем не менее, элементы в двух массивах идентичны. Если бы первый элемент oldArray был NSMutableDictionary, и вы добавили к нему ключ, вы бы увидели это изменение и на первом элементе newArray (поскольку эти два объекта одинаковы).

Чтобы сделать глубокую копию, вам нужно будет создать новый массив, и каждый элемент нового массива будет глубокой копией соответствующего элемента старого массива. (Да, это определение рекурсивно).

11 голосов
/ 28 марта 2012

Прежде всего, NSArray не имеет функции глубокого копирования.Однако вы можете сделать функцию глубокого копирования, выполнив следующие действия:

@interface NSArray(deepCopy)

-(NSArray *) deepCopy;

@end

@implementation

-(NSArray *) deepCopy
{
    NSMutableArray *ret = [NSMutableArray array];

    for (id val in self)
    {
        if ([val conformsToProtocol:@protocol(NSCopying)])
        { 
            [ret addObject:[val copy]];
        }
        else
        {
           [ret addObject:val];
        }
    }

    return ret;
}

@end 

Во-вторых, newArray = oldArray не копирует массив .Он просто указывает newArray на массив, на который указывает oldArray.

В-третьих, +arrayWithArray: делает поверхностную копию массива, что означает, что отдельные объекты НЕ копируются.

2 голосов
/ 29 сентября 2016

Вы также можете позвонить [[NSArray alloc] initWithArray:arraytoBeCopied copyItems:YES];

0 голосов
/ 17 июня 2013

В ключевом слове Objective-C «Копировать» просто увеличьте «Сохранить счет» объекта.Таким образом, только использование «Копии» не будет выполнять копирование.

Но когда мы вносим изменение в объект, тогда Objective-C создает копию исходного объекта в это время.

Пожалуйстапоправь меня если я не прав.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...