I have 1 main Master screen (MVC) and 4 other screens that share ~80% of graphic objects. They differ in some label texts, a button with action and some other 20% graphics. Thinking in terms of clean object oriented code architecture, I have started to implement those screens as separate UIViewControllers. But I didn't like having pointers to those 4 MVCs and a duplication of some methods, so I rewrited the code into one UIViewController. Most of graphic objects are UIImageViews that I put on with Interface Builder. So, now the xib file of that "unified" UIViewController is a little bit bloated with overlapping objects from those 4 screens. I also need to have those methods like showScreen1, hideScreen2, showScreen2, hideScreen2, and other methods, so I'm not very happy with this architecture too. I understand that I should not mix those 4 MVCs (screens) and both the code, and xib files would be cleaner but I'm also thing about performance, saving memory loads and etc. What would be your opinions on that? How much memory resources takes the loading of separate UIViewController? Maybe the amount of saved memory is not worth when compared to code cleanness? Again, having 4 separate MVC's would force me to have 4 pointers both to my Master MVCs and 4 pointers to those separate MVCs from my Master MVC, because I need to communicate and navigate between those screens. Another option would to use notifications instead of pointers but it doesn't change the amount of required relations. So please share your thoughts and insights :)
1 Answers
For user interface controls that share the same design perhaps you could use categories, this is what I'm doing in a project. I've added a category to UINavigationBar to show a texture on the bar, added a category to UIBarButtonItem / UIButton for a back & cancel button and since my ViewControllers all share the same background image I've created a UIViewController subclass that contains the default background image - every view controller used in my app inherits from this default view controller.
I would stick with 1 view controller per screen.
Apple doesn't recommend creating giant nibs, this is especially visible in the WWDC 2011 video on storyboarding (check this video out if you're a registered Apple developer). Giant nibs are bad in terms of performance, it takes a lot of time to load all objects and all the objects from the nib stay in memory all the time, even if the objects are on a screen that's currently not being displayed. It's a better approach to have a separate nib per screen.

- 11,779
- 7
- 51
- 92
-
Thanks :) And what about communication between UIViewControllers? What is your approach for navigation between screens (popping & pushing UIViewControllers. Do you use pointers or notifications? – Centurion Aug 07 '11 at 17:34
-
It's a bit unclear what you mean with using pointers / notifications for navigation between screens. Perhaps you could show some code on the meaning of this? – Wolfgang Schreurs Aug 07 '11 at 17:38
-
Well, I'm building quite simple game mostly with UIKit. There are Menu, in-Game, GameManager and 4 other UIViewControllers: screens for showing level tasks, level complete info, level fail and highscore. I need to navigate between those screens during the gameplay. For example, the in-Game MVC gets pushed from Menu MVC. Then, before each level, I'm pushing level tasks MVC. If a player taps the screen then I'm popping level tasks MVC and pushing in-Game MVC. Currently, the 4 screens have pointers to Menu and in-Game MVC and those two have pointers to those 4 MVCs. Kind a mess with pointers :) – Centurion Aug 07 '11 at 20:56
-
One approach I've seen to deal with such situations is to have all view controllers declared in the app delegate and some methods added to the app delegate to navigate between the view controllers. Since every view controller can access the app delegate, the view controllers themselves don't need to contain pointers to other view controllers. Perhaps this approach would be useful for you as well? – Wolfgang Schreurs Aug 07 '11 at 21:03
-
Beautiful idea, thanks :) One more question: how exactly you are implementing shared background? – Centurion Aug 07 '11 at 21:34
-
IMHO, having shared UIImageViews loaded in viewDidLoad method in the subclassed UIViewController does not guarantee that those images will be loaded only once during instantiation and later use of the UIViewController subclass. I guess all 4 instances of custom UIViewController subclass will create duplicate image objects, so isn't it involves creating some singleton? – Centurion Aug 07 '11 at 21:52
-
I believe if an image is loaded using the `-imageNamed:` method, the image will be cached, which at the very least should reduce loading times. But perhaps the same image might be loaded multiple times, though I don't see this as a huge issue, unless I have memory issues. "Premature optimization is the root of all evil" (Donald Knuth) and all that :) – Wolfgang Schreurs Aug 08 '11 at 07:04
-
**Addendum:** if you use the `-imageNamed:` method the image should not be loaded multiple times if you reuse it in your app, according to this link: http://stackoverflow.com/questions/316236/vs-uiimage-imagewithdata/316258#316258 – Wolfgang Schreurs Aug 08 '11 at 07:42
-
All right, maybe I'm a little bit obsessed about optimization :) but the reason is I'm trying to do things in the right way at the beginning. Also, this is impacted by the lack of proper experience :) – Centurion Aug 08 '11 at 08:26
-
@Addendum, what do you think, is interface builder caching images too like UIImage imageNamed: class method? – Centurion Aug 08 '11 at 09:17
-
@Centurion: I would assume so, I have a firm believe Apple's developers are a bunch of very smart people. There is really no reason to load the same image multiple times, especially on a constrained platform like the iPhone :) – Wolfgang Schreurs Aug 08 '11 at 09:44