Câu trả lời:
Như mọi khi với các loại tham chiếu, có hai khái niệm về "bản sao". Tôi chắc rằng bạn biết chúng, nhưng để hoàn thiện.
Bạn muốn cái sau. Nếu đây là một trong những đối tượng của riêng bạn, bạn chỉ cần sử dụng giao thức NSCopying và thực hiện - (id) copyWithZone: (NSZone *) zone. Bạn tự do làm bất cứ điều gì bạn muốn; mặc dù ý tưởng là bạn tạo một bản sao thật của chính mình và gửi lại. Bạn gọi copyWithZone trên tất cả các trường của mình, để tạo một bản sao sâu. Một ví dụ đơn giản là
@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
nó, hay tôi đang thiếu một cái gì đó ở đây?
copyWithZone:
đáp ứng tiêu chí này, do đó nó phải trả về một đối tượng có số lượng giữ lại là +1.
alloc
thay vì allocWithZone:
kể từ khi khu vực được chuyển vào không?
allocWithZone
.
Tài liệu của Apple cho biết
Phiên bản lớp con của phương thức copyWithZone: nên gửi thông báo tới super trước, để kết hợp việc triển khai nó, trừ khi lớp con xuống trực tiếp từ NSObject.
để thêm vào câu trả lời hiện có
@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:'
. Tôi đoán đây chỉ được yêu cầu khi chúng ta đang kế thừa từ một số lớp tùy chỉnh khác mà cụcopyWithZone
Tôi không biết sự khác biệt giữa mã đó và mã của tôi, nhưng tôi gặp vấn đề với giải pháp đó, vì vậy tôi đã đọc thêm một chút và thấy rằng chúng tôi phải thiết lập đối tượng trước khi trả lại. Ý tôi là:
#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;
}
Tôi đã thêm câu trả lời này bởi vì tôi có rất nhiều vấn đề với vấn đề này và tôi không có manh mối về lý do tại sao nó xảy ra. Tôi không biết sự khác biệt, nhưng nó hiệu quả với tôi và có thể nó cũng có ích cho những người khác:)
another.obj = [obj copyWithZone: zone];
Tôi nghĩ rằng dòng này gây ra rò rỉ bộ nhớ, bởi vì bạn truy cập obj
thông qua thuộc tính mà (tôi giả sử) được khai báo là retain
. Vì vậy, số lượng giữ lại sẽ được tăng lên theo thuộc tính và copyWithZone
.
Tôi tin rằng nó phải là:
another.obj = [[obj copyWithZone: zone] autorelease];
hoặc là:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Ngoài ra còn có việc sử dụng toán tử -> để sao chép. Ví dụ:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Lý do ở đây là đối tượng sao chép kết quả nên phản ánh trạng thái của đối tượng ban đầu. Các "." nhà điều hành có thể đưa ra các hiệu ứng phụ vì điều này gọi các getters đến lượt nó có thể chứa logic.