Odpowiedzi:
Jak zawsze w przypadku typów referencyjnych, istnieją dwa pojęcia „kopiowania”. Jestem pewien, że je znasz, ale dla kompletności.
Chcesz tego drugiego. Jeśli jest to jeden z twoich własnych obiektów, wystarczy zaadoptować protokół NSCopying i zaimplementować strefę - (id) copyWithZone: (NSZone *). Możesz robić, co chcesz; chociaż chodzi o to, żeby zrobić prawdziwą kopię siebie i zwrócić ją. Wywołujesz copyWithZone na wszystkich swoich polach, aby utworzyć dokładną kopię. Prosty przykład to
@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
, czy czegoś mi brakuje?
copyWithZone:
spełnia te kryteria, dlatego musi zwrócić obiekt z liczbą zachowań +1.
alloc
zamiast od allocWithZone:
czasu przekazania strefy?
allocWithZone
.
Dokumentacja Apple mówi
Wersja metody copyWithZone: podklasy powinna najpierw wysłać wiadomość do super, aby uwzględnić jej implementację, chyba że podklasa pochodzi bezpośrednio z NSObject.
dodać do istniejącej odpowiedzi
@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:'
. Wydaje mi się, że jest to wymagane tylko wtedy, gdy dziedziczymy z innej klasy niestandardowej, która implementujecopyWithZone
Nie znam różnicy między tym kodem a moim, ale mam problemy z tym rozwiązaniem, więc przeczytałem trochę więcej i stwierdziłem, że musimy ustawić obiekt przed jego zwróceniem. Mam na myśli coś takiego:
#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;
}
Dodałem tę odpowiedź, ponieważ mam wiele problemów z tym problemem i nie mam pojęcia, dlaczego tak się dzieje. Nie znam różnicy, ale działa na mnie i może przyda się też innym :)
another.obj = [obj copyWithZone: zone];
Myślę, że ta linia powoduje wyciek pamięci, ponieważ dostęp do niej uzyskuje się obj
poprzez właściwość, która jest (zakładam) zadeklarowana jako retain
. Tak więc liczba zatrzymań zostanie zwiększona o własność i copyWithZone
.
Uważam, że powinno to być:
another.obj = [[obj copyWithZone: zone] autorelease];
lub:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Istnieje również użycie operatora -> do kopiowania. Na przykład:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Rozumowanie jest takie, że wynikowy skopiowany obiekt powinien odzwierciedlać stan oryginalnego obiektu. „.” Operator mógłby wprowadzić efekty uboczne, ponieważ wywołuje metody pobierające, które z kolei mogą zawierać logikę.