views:

46

answers:

3

Scenario 1: For a UIViewController, is it better to (1) create an ivar for a UIView that I access again in 1 or 2 functions outside of loadView? Or, (2) should I just tag it in loadView and then use - (UIView *)viewWithTag:(NSInteger)tag to access it again in the other functions? I'm guessing that option 1 increases the memory by the size of a pointer, so 32/64-bits, and creates accessor methods (assuming I declare @property & @synthesize), and then requires releasing the ivar in dealloc and setting it to nil in viewDidUnload... and that option 2 saves memory, has less setup code, but costs some processing time and a little extra code to find the view by its tag. Am I right about all this?

In this scenario, it feels best to use an ivar, but I'm not sure.

Scenario 2: What about for a custom subclass of UIView that has 5 subviews? Bearing in mind that I'll have about 30 instances of this custom subclass in memory at a given time (They'll be subviews of tableViewCells.), should I use 5 ivars for the subviews, or should I tag them all?

In this scenario, I'm thinking the memory saved by tagging them all would be worth the small performance hit of searching for them with - (UIView *)viewWithTag:(NSInteger)tag.

Thoughts?

Thanks!

Matt

+2  A: 

I think you're asking the wrong question.

It seems to me that either the memory required to store 5 pointers, or the time required to look up 5 views using viewWithTag: is going to be negligible in the grand scheme of things.

Choose whichever solution you find makes your code easiest to write, understand, and maintain.

In the unlikely event that actual profiling of time/memory usage indicates that your chosen solution is a problem, consider the other option. Anything else is premature optimization.

David Gelhar
+4  A: 

Matt,

Considering that difference in memory usage is negligible (unless you're going to have 100 of these views, in which case you might want to look into how you can reuse some of those views), you should probably consider what would make your code more readable and maintainable. I personally think that using an ivar would be more readable, but it's also possible that for your particular case using tags would be more readable.

When writing code, I always try to think about the person who's going to reading the code a year or two years from now. That person might be me, or it might be someone else, but either way, I know that person will appreciate readable code. They're less likely to thank me for saving 1k of memory on a device that has at least 128 MB of RAM.

Jacques
+3  A: 

Consider, for a moment, that each view is backed by a CALayer. IIRC, views are about 44 bytes (plus foo), layers are about 44 bytes (times 3, since there's a presentation tree and render tree), and layers which do any rendering are backed by bitmap contexts.

Or, for a more straightforward comparison: Each pointer consumes as much memory as a single pixel.

I use tags only where they make my life easier:

  • Lots if similar views in a nib (a pile of buttons, each selecting a different colour). I could wire up a bunch of outlets, but then the code would have to deal with a bunch of ivars instead of a bit of arithmetic).
  • Lots of subviews with similar functionality (e.g. "pages" in a scroll view, or cell-like views in a UITableView-like container). I could keep track of them in an array, but I'm feeling lazy today.
  • Whenever I need a view to store an extra integer (e.g. a page number). There are plenty of other ways (subclassing, "associated objects", sticking values in layer.style...). This is generally relevant to the first two places.

Also, remember that [v viewWithTag:tag] can return v, any subview, any subview-of-subview... Consider a class FooView which has a "content view" with tag 1, and a "toolbar view" with tag 2:

FooView * f1 = ...;
FooView * f2 = ...;
[f1.contentView addSubview:f2];
NSLog(@"%@ %@", f1.toolbarView, f2.toolbarView);

What does it print? Well, they both could be f2's toolbar!

Yes, Apple could make the search more sensible (it could continue the search until it found the least-deep match, or use iterative-deepening depth first search), but I'd assume that it performed simple depth-first search unless the documentation says otherwise.

tc.