Weird Xcode 6 Beta 4 [UIImage imageNamed:] behavior

514 views Asked by At

Historically I've successfully used the == comparator when comparing an image in an imageView to some predefined image using [UIImage imageNamed:]. This is because I receive the same object when calling [UIImage imageNamed:] repeatedly with the same filename, such as:

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a1433a0>

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a1433a0>

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a1433a0>

Using Xcode 6 Beta 4, a number of my unit tests are failing when trying to compare an image in an imageView to an expected image, and it seems that is because I am given a unique instance of the image with a given filename each time, rather than the old behavior explained above. When doing the same thing in Xcode 6 Beta 4, I get this:

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a691f00>

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a6a1d00>

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a1f3230>

(lldb) po [UIImage imageNamed:@"foo.png"]
<UIImage: 0x7a6a1fd0>

Is this expected behavior, something I'm missing in the documentation for UIImage, perhaps an implementation issue I should address differently, or is this something I should file with Apple as a bug? Any insights?

2

There are 2 answers

3
Ayu On

I just tried the same thing in iOS 7 and I had the expected output (i.e same object for all vars) But when I run the same thing in iOS 8 I get different objects. (Both times using Xcode 6 beta 4)

So I checked the docs for iOS 7 we have:

 +(UIImage *)imageNamed:(NSString *)name 

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.

iOS 8:

 +(UIImage *)imageNamed:(NSString *)name 

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method locates and loads the image data from disk or asset catalog, and then returns the resulting object. You can not assume that this method is thread safe.

There is nothing in the seconde text that specifies exactly that this call caches the data, so maybe it's attended (Which doesn't make any sense) or it's a bug. My advice is to send a bug report, and see what they'll say.

Ayu.

7
zaph On

Do not compare objects by their instances addresses if what you want is to compare their content!

Sure it works sometimes by coincidence but there is no guarantee—as you have found out.

Apple is free to change such implementation details at will without notice.

Write your own compare method, perhaps comparing just an initial portion since this is test code.