14

I want to display so many images in table cells. I knew two methods to show an image.

One is creating an instance to UIImageView and show it

CGRect rect=CGRectMake(x,y,width,height);
UIImageView *image=[[UIImageView alloc]initWithFrame:rect];
[image setImage:[UIImage imageNamed:@"sample.jpg"]];

Another method is,

CGRect rect=CGRectMake(x,y,width,height);
[[UIImage imageNamed:@"sample.jpg"] drawInRect:rect];

Now, my question is, what is the difference between these two? Which one is efficient? Or someother function is available better than this?

Thanks in advance....

Vladimir
  • 170,431
  • 36
  • 387
  • 313

2 Answers2

32

Using the drawInRect: method has CoreGraphics draw the image into the active CGContext using the CPU. Assuming you're in a UIView's drawRect: method, this will paint the image into the view's buffer.

UIImageView uses whichever image is assigned to it as it's backing buffer instead of using the slower drawRect:. The GPU then references this buffer directly when the screen is composited via QuartzCore.

rpetrich
  • 32,196
  • 6
  • 66
  • 89
  • +1 for a GREAT answer. I've been trying to get my head around the distinction between those two for a while now. So `UIImageView` is always the way to go, then? Are there cases where `drawRect:`'ing the image directly is preferable? – Dan Ray Oct 01 '10 at 13:23
  • The only situation I can see it being slower is when compositing a static background scene from many small images and then animating content on top of it without changing the background. In that case the GPU will have to recomposite both the moving content over top and the entire background scene each frame. This is a corner case of course. – rpetrich Oct 01 '10 at 16:06
  • 3
    One situation where `-drawRect:` is an advantage is when you want smooth scrolling performance and you have PNGs that have transparency. On older hardware, the GPU can't handle scrolling a whole lot of transparent views at the same time without dropping frames. One way around this is to do all of your compositing in `-drawRect:`, which converts this heavy GPU work into a one-time heavy CPU job. This is a relatively common scenario in graphics intense table view cells, although it's not as much of an issue with the iPhone 4 and iPad due to the faster GPUs. – Nick Forge Feb 10 '11 at 00:17
  • Nick Forge: That brings up a good point. Set `UIView.opaque` to `YES` where possible. – rpetrich Feb 11 '11 at 20:46
  • I'd like to know the difference as well, but I don't fully understand the answer because several terms such as 'CGContext, cpu,gnu, view's buffer, backing buffer' are not clear to me. Can someone recommend me a book to start understanding the concepts behind these graphics-related talk? – eugene Jun 28 '12 at 02:27
  • Adding onto Nick Forge's comment: One can now set the `shouldRasterize` property a view's layer to `YES` as an alternative to drawing on the CPU. This has a similar effect of caching the heavy work and may have better performance than drawing on the CPU in some circumstances. – rpetrich Jun 28 '12 at 03:22
  • @Eugene: Are you looking for a general graphics book, or something specific to QuartzCore and iOS's implementation of it? – rpetrich Jun 28 '12 at 03:23
  • @rpetrich: doesn't have to be specific to QuartzCore and iOS, general concepts are fine. But if it's easier to grasp concepts with actual library, yes it would be good to go with iOS-related implementations. Thanks for the interest – eugene Jun 28 '12 at 07:51
0

UIImageView is a UIView subclass. By adding it to the view hierarchy you get all the free benefits: animations, size properties, affine transoforms, etc. Plus, you are able to change the underlying UIImage any time you want.

On the other hand, calling drawInRect: will just draw the image where you tell it to, but not interact with the UIView hierarchy, so you don't gain any of the benefits from having it on the view hierarchy.

I would think (have not tried it), that drawing the image directly is faster, but I would think in most of the cases having a UIImageView is a better idea.

pgb
  • 24,813
  • 12
  • 83
  • 113