1

Between the two methods, which is better/more efficient? More specifically, which should be used, or is there a proper time to use one over the other?

UIImage *img = [UIImage imageWithContentsOfFile:filePath];

or

UIImage *img = [[UIImage alloc] initWithContentsOfFile:filePath];

Thanks!

EDIT: I should have mentioned that I'm using ARC.

jonstaff
  • 2,672
  • 2
  • 19
  • 18

3 Answers3

7

The first returns an autoreleased object. There is a high chance that the imageWithContentsOfFile: version invokes the standard constructor, so there shouldn't be any noticeable difference in speed/efficiency. Both perform and are used the same way in an ARC environment.

Alexander
  • 8,117
  • 1
  • 35
  • 46
2

The big difference resides in objective-c reference counting. When you init an object you are claiming ownership over it. This means you are responsible for releasing it when you don't need the object anymore, i.e. by calling [img release].

When you get a reference to a method whose name begins with something other than init or copy (I'm not sure if there is any other prefix) these objects are registered with an NSAutoreleasePool and are automatically released when the pool is drained.

You can check this like this:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

UIImage *img1 = [UIImage imageWithContentsOfFile:filePath];
UIImage *img2 = [[UIImage alloc] initWithContentsOfFile:filePath];

[pool drain];

NSLog(@"%@", [img1 retainCount]); // 1
NSLog(@"%@", [img2 retainCount]); // 0 or invalid mem access, not sure

To implement the autorelease behaviour, which you should when you are creating an acessor for a object and consequently delegating the ownership to the accessor method and not the calling one, you do something like:

[obj autorelease];

As for the NSAutoreleasePooldon't worry much about its working since one pool is already setup for you by the NSApplicationMain method in the main.c file.

You can further investigate this mechanism in NSObject Protocol Reference and Advanced Memory Management.

Tiago
  • 1,337
  • 11
  • 17
1

Because in the beginning i was declaring all my images with alloc and if in the end of a certain function i returned the image created with alloc i had to autorelease that image, because memory leak problems. Now using the first declaration i don't need to release anything

That is exactly correct when you "vend" an object. But in other cases, when you create an object on iOS, where you have a choice between obtaining a ready-made autoreleased object and calling alloc followed by release, Apple wants you to use alloc and release, because this keeps the lifetime of the object short and under your control.

The problem here is that autoreleased objects live in the autorelease pool and can pile up until the pool is drained, whenever that may be.

Another thing to watch out for is loops. You may generate autoreleased objects without being aware of it, and they just pile up in the pool. The solution is to create your own autorelease pool at the start of the loop and release it at the end of the loop, so that the objects are released each time thru the loop.

EDIT - 12/18/2011: But with iOS 5 and the coming of ARC, the autorelease mechanism is far more efficient, and there is no such thing as release, so the distinction between alloc-init and a convenience constructor vending an autoreleased object becomes moot. (Also it's now an @autoreleasepool block rather than an autorelease pool (pseudo-)object.)

got from this question.

Community
  • 1
  • 1
Nirav Gadhiya
  • 6,342
  • 2
  • 37
  • 76