Ответы:
Как всегда со ссылочными типами, есть два понятия «копия». Я уверен, что вы их знаете, но для полноты картины.
Вы хотите последнего. Если это один из ваших собственных объектов, вам нужно просто принять протокол 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
не должен, или я что-то здесь упускаю?
copyWithZone:
соответствует этим критериям, поэтому он должен возвращать объект со счетчиком удержания +1.
alloc
вместо, allocWithZone:
так как зона была передана?
allocWithZone
.
В документации Apple говорится
Версия подкласса метода copyWithZone: должна сначала отправить сообщение в super, чтобы включить его реализацию, если только подкласс не наследуется непосредственно от 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;
}
No visible @interface for 'NSObject' declares the selector 'copyWithZone:'
. Я предполагаю, что это требуется только тогда, когда мы наследуем от какого-то другого настраиваемого класса, который реализуетcopyWithZone
Я не знаю разницы между этим кодом и моим, но у меня есть проблемы с этим решением, поэтому я прочитал немного больше и обнаружил, что мы должны установить объект, прежде чем возвращать его. Я имею в виду что-то вроде:
#import <Foundation/Foundation.h>
@interface YourObject : NSObject <NSCopying>
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *line;
@property (strong, nonatomic) NSMutableString *tags;
@property (strong, nonatomic) NSString *htmlSource;
@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.name];
[copy setLinea: self.line];
[copy setTags: self.tags];
[copy setHtmlSource: self.htmlSource];
return copy;
}
Я добавил этот ответ, потому что у меня много проблем с этой проблемой, и я понятия не имею, почему это происходит. Я не знаю разницы, но у меня это работает и, возможно, может быть полезно и для других :)
another.obj = [obj copyWithZone: zone];
Я думаю, что эта строка вызывает утечку памяти, потому что вы obj
получаете доступ к свойству through, которое (я полагаю) объявлено как retain
. Таким образом, счетчик удержания будет увеличиваться за счет собственности и copyWithZone
.
Я считаю, что это должно быть:
another.obj = [[obj copyWithZone: zone] autorelease];
или:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Также для копирования используется оператор ->. Например:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Причина здесь в том, что полученный скопированный объект должен отражать состояние исходного объекта. Знак "." Оператор может вызвать побочные эффекты, поскольку он вызывает геттеры, которые, в свою очередь, могут содержать логику.