iOS:如何在启用 ARC 的情况下从内存中删除对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7631643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:43:24  来源:igfitidea点击:

iOS: How to remove object from memory with ARC enabled?

iosautomatic-ref-counting

提问by icant

I am developing an iOS app with the iOS 5 SDK, Automatic Reference Counting is enabled. But I have a specific object that is being created in large numbers and must be released after a second because otherwise the device will become very slow. It looks like they are not released, as the device is very slow. Is there a way to manually release an object when ARC is enabled?

我正在使用 iOS 5 SDK 开发 iOS 应用程序,启用了自动引用计数。但是我有一个正在大量创建的特定对象,必须在一秒钟后释放,否则设备会变得非常慢。看起来它们没有发布,因为设备非常慢。启用 ARC 时,有没有办法手动释放对象?

EDIT: My code, this is called 200 times a second to generate sparkles. They fade out after 0.8 seconds so they are useless after then.

编辑:我的代码,这被称为每秒 200 次以产生火花。它们在 0.8 秒后淡出,因此在那之后它们就没有用了。

    int xanimationdiff = arc4random() % 30;
    int yanimationdiff = arc4random() % 30;
    if (arc4random()%2 == 0) {
        xanimationdiff = xanimationdiff * -1;
    }
    if (arc4random()%2 == 0) {
        yanimationdiff = yanimationdiff * -1;
    }

    Sparkle *newSparkle = [[Sparkle alloc] initWithFrame:CGRectMake(20 + arc4random() % 280, 20, 10, 10)];
    //[newSparkle setTransform:CGAffineTransformMakeRotation(arc4random() * (M_PI * 360 / 180))]; //Rotatie instellen (was niet mooi, net sneeuw)
    [self.view addSubview:newSparkle];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.8];
    [newSparkle setFrame:CGRectMake(newSparkle.frame.origin.x - xanimationdiff, newSparkle.frame.origin.y - yanimationdiff, newSparkle.frame.size.width, newSparkle.frame.size.height)];
    newSparkle.alpha = 0;
    [UIView commitAnimations];

The sparkle object code:

闪光对象代码:

#import "Sparkle.h"

@implementation Sparkle

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"sparkle.png"]]];
    }
    return self;
}

@end

回答by The Rat

Object* myObject = [[Object alloc] init];     
myObject = nil; // poof...

EDIT: You cannot directly control when an object is released BUT you can indirectly cause it to happen. How? Remember what ARC does EXACTLY. Unlike human coding convention, ARC parses your code and inserts release statements AS SOON AS OBJECTS CAN be released. This frees up the memory for new allocations straight away, which is awesome/necessary. Meaning, setting an object to nil, or simply allowing a variable to go out of scope ... something that CAUSES A 0 RETAIN COUNT forces ARC to place its release calls there. It must ... because it would leak otherwise.

编辑:您无法直接控制对象何时被释放,但您可以间接导致它发生。如何?记住 ARC 的作用。与人类编码约定不同,ARC 解析您的代码并在对象可以被释放时插入释放语句。这会立即释放新分配的内存,这很棒/必要。意思是,将对象设置为 nil,或者只是允许变量超出范围......导致 0 RETAIN COUNT 强制 ARC 将其释放调用放在那里的东西。它必须......因为否则它会泄漏。

回答by rvijay007

Just surround the section of code that is going to be called 200 times with an @autoreleasepool { ... } statement. This will cause the memory to be deallocated immediately as opposed to waiting for the control to go all the way back up the event chain to the top level autorelease pool.

只需用@autoreleasepool { ... } 语句包围将要调用 200 次的代码部分。这将导致内存立即被释放,而不是等待控件沿着事件链一直返回到顶级自动释放池。

回答by icant

I found the answer, it was actually really stupid. I didn't remove the sparkles from the superview. Now I remove them after 0.8 seconds with a timer and it performs great again :)

我找到了答案,这真的很愚蠢。我没有从超级视图中删除闪光。现在我用计时器在 0.8 秒后删除它们,它再次表现出色:)

回答by lxt

With ARC you cannot calldealloc, release, or retain, although you can still retain and release CoreFoundation objects (NB: you can implement deallocmethods for your own custom subclasses, but you can't call super dealloc). So the simple answer is 'no', you unfortunately cannot manually release an object when using ARC.

使用 ARC,您不能调用deallocreleaseretain,尽管您仍然可以保留和释放 CoreFoundation 对象(注意:您可以dealloc为自己的自定义子类实现方法,但不能调用super dealloc)。所以简单的答案是“不”,不幸的是,您无法在使用 ARC 时手动释放对象。

I'd double check you're sure they're not being released, because in theory if you no longer reference an object it should be released. What do you do with these objects once you create them? You simply create them then immediately destroy them?

我会仔细检查你确定它们没有被释放,因为理论上如果你不再引用一个对象,它应该被释放。创建这些对象后,您会如何处理它们?您只是创建它们然后立即销毁它们?

Perhaps you could post the code you're using / the property declarations - are these weakor strongreferenced objects?

也许您可以发布您正在使用的代码/属性声明 - 这些weakstrong引用的对象?