Мне нужно выполнить глубокую копию пользовательского объекта, который имеет собственные объекты. Я читал и немного смущен относительно того, как наследовать NSCopying и как использовать NSCopyObject. Может ли кто-нибудь помочь мне? Спасибо за прочтение!Как скопировать объект в объекте c
ответ
Как всегда с ссылочными типами существует два понятия «копировать». Я уверен, что вы их знаете, но для полноты.
- Побитовая копия. В этом случае мы просто копируем бит памяти для бит - это то, что делает NSCopyObject. Почти всегда, это не то, что вы хотите. Объекты имеют внутреннее состояние, другие объекты и т. Д., И часто делают предположения, что они являются единственными, у которых есть ссылки на эти данные. Побитовые копии нарушают это предположение.
- Глубокая, логическая копия. В этом случае мы создаем копию объекта, но фактически не выполняем его по-разному - мы хотим, чтобы объект, который ведет себя одинаково для всех целей и целей, но не является (обязательно) идентичным памяти клоном оригинала - в руководстве Objective C такой объект «функционально независим» от оригинала. Поскольку механизмы создания этих «интеллектуальных» копий варьируются от класса к классу, мы просим сами объекты выполнить их. Это протокол NSCopying.
Вы хотите последнего. Если это один из ваших собственных объектов, вам нужно просто принять протокол NSCopying и реализовать - (id) copyWithZone: (NSZone *) зону. Вы свободны делать все, что хотите; хотя идея заключается в том, что вы делаете реальную копию себя и возвращаете ее. Вы вызываете copyWithZone во всех своих полях, чтобы сделать глубокую копию. Простой пример
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
// We'll ignore the zone for now
YourClass *another = [[YourClass alloc] init];
another.obj = [obj copyWithZone: zone];
return another;
}
Но вы делаете получателя скопированного объекта ответственным за его освобождение! Разве вы не 'autorelease' его, или я что-то упустил здесь? – bobobobo
@bobobobo: Нет, основное правило памяти Objective-C управление: вы получаете право собственности на объект, если вы его создаете, используя метод, имя которого начинается с «alloc» или «new» или содержит «copy». 'copyWithZone:' соответствует этим критериям, поэтому он должен возвращать объект с сохранением count +1. –
@Adam Есть ли причина использовать 'alloc' вместо' allocWithZone: ', поскольку зона была передана i n? – Richard
Apple, документация говорит
A subclass version of the copyWithZone: method should send the message to super first, to incorporate its implementation, unless the subclass descends directly from NSObject.
добавить к существующему ответу
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
YourClass *another = [super copyWithZone:zone];
another.obj = [obj copyWithZone: zone];
return another;
}
Поскольку YourClass спускается непосредственно из NSObject, я не думаю, что это необходимо здесь – Mike
Хорошая точка, но это общее правило, если это длинная иерархия классов. –
У меня есть ошибка: 'Нет видимого @interface для 'NSObject' объявляет селектор 'copyWithZone:''. Я предполагаю, что это требуется только тогда, когда мы наследуем какой-то другой пользовательский класс, который реализует 'copyWithZone' – Sam
another.obj = [obj copyWithZone: zone];
Я думаю, что эта линия вызывает утечку памяти, потому что вам доступ до obj
через имущество, которое (я предполагаю) объявлено как retain
. Таким образом, сохранить кол-во будет увеличено по собственности и copyWithZone
.
Я считаю, что это должно быть:
another.obj = [[obj copyWithZone: zone] autorelease];
или:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Нет, методы alloc, copy, mutableCopy, new должны возвращать неавтореализованные объекты. – kovpas
@kovpas, вы уверены, что вы меня правильно поняли? Я не говорю о возвращенном объекте, я говорю о его полях данных. –
да, мой плохой, извините. не могли бы вы отредактировать свой ответ так или иначе, чтобы я мог удалить минус? :)) – kovpas
я не знаю различие между этим кодом и моим, но у меня есть проблемы с этим решением, так что я прочитал немного больше и обнаружил, что мы должны установить объект перед его возвратом. я имею в виду что-то вроде
#import <Foundation/Foundation.h>
@interface YourObject : NSObject <NSCopying>
@property (strong, nonatomic) NSString *nombre;//nombre del medicamento
@property (strong, nonatomic) NSString *linea;//linea a la que pertenece
@property (strong, nonatomic) NSMutableString *tags;//palabras por las que se puede encontrar en el buscador
@property (strong, nonatomic) NSString *htmlSource;//código html para mostrar su contenido
@property (strong, nonatomic) NSMutableString *obj;
-(id) copyWithZone: (NSZone *) zone;
@end
@implementation YourObject
-(id) copyWithZone: (NSZone *) zone
{
YourObject *copy = [[YourObject allocWithZone: zone] init];
[copy setNombre: self.nombre];
[copy setLinea: self.linea];
[copy setTags: self.tags];
[copy setHtmlSource: self.htmlSource];
return copy;
}
я помещал этот ответ причину, у меня есть много проблем, связанных с этим вопросом, и я понятия не имеют о том, почему!, я не знаю разницу, но это работает и, возможно, может быть полезным:)
Существует также использование оператора -> для копирования. Например:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Приведенная здесь копия объекта должна отражать состояние исходного объекта. «.«оператор может вводить побочные эффекты, так как это вызывает геттеры, которые, в свою очередь, могут содержать логику.
- 1. Как увеличить объект Json в объекте-c
- 2. Как сбросить объект в объекте C
- 3. Как де-сериализовать объект в объекте-C
- 4. Как скопировать данные объекта класса в объект edmx в C#
- 5. C# - Как скопировать/создать объект как декандальный
- 6. Как скопировать объект, который унаследован от объекта im, пытающегося скопировать?
- 7. конвертировать объект в JSON в объекте c
- 8. C# Entityframework как скопировать/клонировать объект
- 9. Ссылка на объект Nil в объекте C
- 10. генерировать js объект литерал в объекте C
- 11. Скопировать объект в Python?
- 12. angular2: как скопировать объект в другой объект
- 13. Как скопировать объект JavaScript в другой объект?
- 14. Как скопировать объект NetStream?
- 15. Как скопировать нераскрытый объект?
- 16. Как скопировать объект CakePHP
- 17. Как скопировать объект в Java
- 18. Как скопировать результаты в объект?
- 19. Как скопировать объект в Scala?
- 20. Как скопировать объект в Java?
- 21. Как скопировать объект в Qt?
- 22. Пытается скопировать строку в текстовое поле в объекте-C
- 23. Как скопировать объект CImage?
- 24. Объект Java в объекте
- 25. Объект запроса в объекте
- 26. Объект доступа в объекте
- 27. JSON объект в объекте
- 28. Объект в объекте?
- 29. Скопировать объект в другой
- 30. объект печати в объекте
Великий [учебник] (http://www.techotopia.com/index.php/Copying_Objects_in_Objective-C) для понимания копии, mutableCopy и copyWithZone – horkavlna