Why doesn't ARC free memory when using [NSDate date] but works fine using [[NSDate alloc] init]?

混江龙づ霸主 提交于 2019-12-05 04:10:24

Autorelease objects are released eventually, whereas in the alloc/init case they are released as soon as they're not used anymore.

This behavior causes your objects to persist in memory for the whole loop in case they are autoreleased for the being released later on, whereas if you alloc/init them, a release method is sent within the loop body.

You can easily make the body loop memory-efficient by wrapping it in a @autoreleasepool like follows:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    @autoreleasepool {
        NSDate* d;
        for(int i=0; i<1000000; i++){
            d = [NSDate date];
        }
    }
}

This will give a hint to ARC, signaling that you want to create and release an autorelease pool at every loop iteration.

In the specific case the easiest option would probably be to use alloc/init methods, in order for the compiler to do the right thing automatically, but if you have a loop body with many factory methods that return autoreleased instances, the @autoreleasepool block is probably a great way to go.

As a final remark, @autoreleasepool is not an ARC exclusive. It used to exist since LLVM 3.0 it, and with sufficient modern targets (namely iOS5 and OSX 10.7 on) it's known to be much faster than the old-fashioned NSAutoreleasePool.

Bryan

[NSDate date] is creating an auto-released object that will be released the next time your program enters the event loop.

The other case is released within the loop by ARC.

If you really want to do something like this you can create your own auto-release pool and drain it periodically. See for example Objective-C: Why is autorelease (@autoreleasepool) still needed with ARC?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!