iPhone - copyWithZone 泄漏

发布于 2024-09-27 11:28:49 字数 859 浏览 8 评论 0原文

在设备上测试我的应用程序,当我调用自定义对象的副本时,它返回泄漏,我不明白为什么。

这是调用:

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    [arr addObject:[sp copy]];
}
self.partList = arr;
[arr release];

这是方法:

- (id)copyWithZone:(NSZone *)zone {
    SinglePart *copy = [[[self class] allocWithZone:zone] initWithSinglePart:self];
    [copy loadImage];
    return copy;
}

这是 copyWithZone 调用的方法:

- (id)initWithSinglePart:(SinglePart *)copyFrom {
    if (self = [super init]) {
        self.imagePath = [copyFrom.imagePath copy];
        self.color = [UIColor colorWithCGColor:copyFrom.color.CGColor];
        self.hasOwnColor = copyFrom.hasOwnColor;
        self.blendingMode = copyFrom.blendingMode;
    }
    return self;
 }

Testing my app on the device it returns a leak whe i call the copy of a custom object ande i can't understand why.

this is the call:

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    [arr addObject:[sp copy]];
}
self.partList = arr;
[arr release];

this is the method:

- (id)copyWithZone:(NSZone *)zone {
    SinglePart *copy = [[[self class] allocWithZone:zone] initWithSinglePart:self];
    [copy loadImage];
    return copy;
}

this is the method that is called by copyWithZone:

- (id)initWithSinglePart:(SinglePart *)copyFrom {
    if (self = [super init]) {
        self.imagePath = [copyFrom.imagePath copy];
        self.color = [UIColor colorWithCGColor:copyFrom.color.CGColor];
        self.hasOwnColor = copyFrom.hasOwnColor;
        self.blendingMode = copyFrom.blendingMode;
    }
    return self;
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哽咽笑 2024-10-04 11:28:49

copy 返回一个保留计数为 1 的新对象。这意味着您需要释放新对象,但您没有这样做。

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    SingPart *theCopy = [sp copy];
    [arr addObject:theCopy];
    [theCopy release];
}
self.partList = arr;
[arr release];

即使您的自定义 copyWithZone: 方法也会初始化一个对象,但不会自动释放它,这是 copy 方法的预期行为。复制必须像保留或初始化一样平衡,这意味着您必须在某个时刻平衡它与释放。

最后,您的 initWithSinglePart: 方法也会泄漏 imagePath 。在这种情况下,如果您将 imagePath 属性声明为 copy 而不是 retain,那么您根本不需要手动执行此操作。然后,您只需分配值并让属性设置器为您完成即可。

// Header
@property (copy) NSString *imagePath;

// Now this will do the copy for you
self.imagePath = copyFrom.imagePath;

copy returns a new object with retain count 1. Meaning you need to release the new object, which you are not doing.

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    SingPart *theCopy = [sp copy];
    [arr addObject:theCopy];
    [theCopy release];
}
self.partList = arr;
[arr release];

Even your custom copyWithZone: method inits an object, but does not autorelease it, which is the expected behavior of a copy method. Copy must be balanced just like a retain or init, meaning you must balance it with release at some point.

Lastly, your initWithSinglePart: method leaks the imagePath as well. In this case if you declare the imagePath property as copy instead of retain then you don't need to do this manually at all. Then you simply assign the value and let the property setter do it for you.

// Header
@property (copy) NSString *imagePath;

// Now this will do the copy for you
self.imagePath = copyFrom.imagePath;
养猫人 2024-10-04 11:28:49

另外,属性 imagePath 是使用 retaincopy 语义定义的吗?

如果是这样,您需要在此处添加自动释放:

self.imagePath = [[copyFrom.imagePath copy] autorelease];

因为默认设置器也会保留/复制它。

因此,您要么需要自动释放,要么省略“self”。绕过默认设置器。

Also, is the property imagePath defined with retain or copy semantics?

If so you need to add an autorelease here:

self.imagePath = [[copyFrom.imagePath copy] autorelease];

because the default setter will retain/copy it too.

So, you either need to autorelease, or omit the "self." to bypass the default setter.

方圜几里 2024-10-04 11:28:49

您正在制作 sp 的副本,然后将其添加到数组中。然后数组保留该对象,因此您的保留计数现在为 2。

最后您释放了 arr,从而使其项目的保留计数为 1。

您应该向 sp 添加另一个释放 对象,或者不使用copy

试试这个:

self.partList = [NSMutableArray arrayWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    [arr addObject:sp];
}

You are making a copy of sp and then adding it to the array. The array then retains the object so your retain count is now 2.

In the end you release arr, thus making the retain count of it's items 1.

You should either add another release to the sp objects, or not use copy.

Try this:

self.partList = [NSMutableArray arrayWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    [arr addObject:sp];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文