How to share values between classes without using globals? - objective-c

I built 5 UITableViews: Continent, Country, Subcountry, Region and Subregion respectively.
The data for every UITableView is being stored in a database.
On every navigation I retrieve essential data and pass (prepareToSegue) it to next UITableView with the set of token variables I defined in every class. All are similar.
Continent(country.ContinentID=self.continentID)
--> Country (region.CountryID=self.countryID)
I have a feeling that I am doing it wrong, in some kind of ugly way. Can you advice me how to implement this task more smart and, lets assume, in professional way? I'd like to get rid of this bundle of int vars in every class.
P.S Please don't advise using global variables. I read about them here, and the globals are defined as more-evil-than a goto statement.

One possible solution is to create all controllers by a separate class that would keep track of the essential data and pass them to the controllers as needed during creation. This is illustrated in my sample Xcode project on GitHub. Stay away from singletons, they are little more than glorified globals and there are many good arguments against them (some of which are explained in this blog post).

I would recommend the Singleton design pattern to answer your needs - Creating a "DataManager" to hold and maintain all your data objects so that you can access them from anywhere across your controllers is convenient and if you implement it correctly, it ensures persistence and good performance.

Related

Do I need to use a delegate to maintain the MVC pattern when accessing NSUserDefaults?

Still on assignment 4 of cs193p. - http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/assignments/Assignment%204_2.pdf
I've fully (ish) implemented the displaying photos from a list of places.
I'm adding the second tab of the application (required tasks 10 & 11) , which is to generate and display a list of the 20 most recent photos viewed in chronological order.
My question relates to the MVC pattern and setting/accesing NSUserdefaults.
Basically, anytime a photo is viewed, a property list stored in NSUserdefaults needs to be updated.
When selecting the "recent photos" tab, those values need to be read and displayed, so that the user can select a recently viewed photo, and then view it by selecting it.
I think I can implement this quite easily from a writing lines of code and it will probably work point of view.
I've seen this question: CS193P UITabBarController MVC Help on Assignment 4 which is kind of related, but doesn't really address my more theoretical question about the nature of the pattern.
My question is more about the MVC pattern.
In the lecture, when he demonstrated this with favourite graphs, from the previous calculator assignment he used a delegate to communicate between the favourites list view controller and the graphviewController (see diagram on slide 64 of lecture 9). http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/lectures/Lecture%209_1.pdf
I'm trying to work out if I need to do something similar to avoid breaking the MVC pattern, or if I can just use NSUserdefaults in both the viewWillLoad of my imageViewController to add a photo to the favourites and and then in my setter in RecentImagesViewController. I know NSUserdefaults is designed for persistence, it just feels a bit like I"m using a global variable.
I realise this question is worded in a way which makes it difficult to follow if you aren't familiar with the cs193p course - sorry.
Thanks for any advice!!
I don't think you have to transform something rather simple in something complex. You are storing the favorites using the NSUserDefaults and that's it. The place where you are using might not be the best (I am not saying the viewWillLoad is a bad place, I don't know your code), but I don't think you need a delegate to just update the NSUserDefaults. Botton line, don't forget the KISS principle. :)
Well, it probably feels like you're using a global variable because the user defaults themselves are a global concept. And they should be. You don't want different parts of the app operating on unsynchronized versions of user preferences.
But, if you use the term variable in the sense of an old C/C++ global static piece of data, then, no ... that's not what it is. NSUserDefaults was written by Apple to be a nice tidy class that encapsulates the user default data. The fact that you use [NSUserDefaults standardUserDefaults] to access something like a singleton instance (not sure if that's how Apple chose to implement it) still doesn't mean it's a true global variable.
I agree with Jacky Boy that keeping it simple is best, but your question is really asking whether doing it the way you are is a violation of the MVC pattern (and adhering slavishly to a pattern is not always going to make your code the best). That depends on what you consider the model to be. I could justify saying that Apple built NSUserDefaults to be a model layer encapsulation of the preferences data. So, there you have your model layer, and your controllers should be able to use it.
Or do you feel the need to write the entire model layer yourself, in which case your model layer would just have a wrapper for NSUserDefaults. That would seem like overkill for most situations.
Here is maybe one situation that could warrant it. If you have a lot of preference data that seems logically related, but some of it is not appropriate for NSUserDefaults. Perhaps it's a lot of binary data, stored in a hierarchy of objects, and you want to persist it with Core Data. But, it still seems logically related to what you're keeping in NSUserDefaults. Maybe then, you decide to write your own model layer, that encapsulates both the Core Data and NSUserDefaults data. Your view controllers could then use that directly.
But, generally, I think iOS is well designed to have whoever needs to just use the standardUserDefaults object directly.
If I understand the question correctly, it sounds like the setting/loading should be occurring from the appropriate view controller. Creating a delegate (which may or may not be a singleton) that you can call from each of the different tab's view controllers will help prevent you from duplicating code.

Multiple ViewControllers - should I use a singleton object?

I have a new project, kind of a board game, and I'm using a storyboard which has multiple view controllers in it - the game simply moves from one view to the next with the player making various decisions and then loops back.
I have an object which holds information about the player (along with a couple of methods) - the score etc. I obviously only need one instance of this object and as I want each View Controller to access the same instance, should it be a singleton? I've never used them before and I've read they're often over-used, so I just want to check if this is the correct way to do this from the start. Many thanks.
What you have described is the Model for your application, holding the game data and core logic. Is there any reason to make this a singleton rather than passing it between your controllers?!
I would assume one controller calls the next and so can pass this information across?! We use singletons for services and the like but not for model data, it's not really the point of them in our experience.
I personally have nothing against singletons, as long as you don't use too many of them in one project. While other people might recommend you use some other mediation for this project, I say go for it—this is exactly what you'd use a singleton for.
Singleton's can be be bad if you are developing a library component, a large server project, or for unit testing. But since you are doing an iphone game don't fret about it, it'll will be easier and faster just to use a singleton.
If you are worried about unit testing, since objetive-c is latebound and singletons are made with factory methods instead of constructors it's not hard to changeout the singleton for your unit test anyway.

Design pattern advice: Using an array of custom objects as a singleton

After a lot of studying, I am starting to code my first app.
In my code I have a class called "Measurement". I want to implement an array of Measurements. This array of Measurements needs to be accessible across multiple view controllers, so I have created a custom class called "MeasurementsArray" for the array, and made it into a singleton.
I have done this, and the code works as expected. But now that I have it working, I want to make sure that I have easy to understand code, and that I am following conventional objective-c design patterns.
If it weren't for fact that I need the array of Measurements to be a singleton, it would seem that this array belongs inside the "Measurement" class as a class method. But my understanding is that there can be only one instance of a class when it is a singleton.
But somehow, having a separate class named "MeasurmentsArray" seems a little hacky to me.
My question:
Am I approaching this the right way, or am I missing something?
If I do need the split off the array of Measurements to a separate class in order to have it be a singleton, does "MeasurementsArray" seem like an appropriate class name? If not, please provide a naming convention you would use for this type of situation.
Edit: After some inital answers, some clarification regarding the function of the app might help.
It is a fitness application that records, saves and tracks body fat percentage and body weight. Every time the user records his body fat and weight, it becomes an instance of the class "Measurement". The array of Measurements is needed in order to track changes in weight and body fat over time. A singleton is needed because multiple view controllers need access to the array.
A singleton is needed because multiple
view controllers need access to the
array.
There are other, better ways to share data between objects than to rely on a singleton.
View controllers are usually created either by the application delegate or by another view controller. The application's data model (in this case, that's your measurements array) is often also created ether by the application delegate. So when the app delegate creates a view controller, it can also give that controller a pointer to the data model. If that controller creates any view controllers, it can likewise share its pointer to the data model.
Passing the data model along from app delegate to view controller and from one view controller to the next makes your code easier to maintain, test, reconfigure, and reuse because it avoids depending on some predetermined, globally accessibly object.
Having a singleton at all may be a wrong move. There are times that a singleton is appropriate, but there's usually a better choice.
It sounds like you may already be implementing something resembling the Model-View-Controller pattern, which would be appropriate. In this context, this array of measurements is part of your model, and it may make sense for it to be a separate class, but there's likely no need for it to be a singleton.
The name MeasurementsArray is implementation-specific. I would be more inclined to call it just Measurements or to give it a name reflecting what the measurements are measuring.
In fact I wonder about the name of your Measurement class. What is it measuring? What does it actually represent?
If you post some code, we might be able to provide more specific ideas.
Based on your update and a bit of thinking, you might want to think about The Repository Pattern. Rather than having your controllers hold the array, they have access to the repository from which they can get it.
My thinking here is that your array of measurements might be supplied by a MeasurementRepository and that while now the data might be a single simple array that the repository just holds, it might evolve to something that is stored in a database per user and with variation over time, so that your repository supplies more complex access.
Rather than having this repository be a singleton (though that is certainly sometimes done), it might better be just created once and then injected into everything that needs it. See http://en.wikipedia.org/wiki/Dependency_injection and Uncle Bob's blog
I feel that a separate class is probably overkill unless it has several methods of its own, in which case it might be justified. This problem may just be an artefact of your app's structure not (yet) being well defined. Is data going to be persistent across sessions? If so, will there be a "manager" class on which you could put a property to retrieve the array; something like allMeasurements on the MeasurementStore class? Another option would be to store the array in your app delegate.
I find that if I continue working on an app, it becomes obvious how I should structure it.
Edit: To elaborate, there's nothing "wrong" with your approach; there's probably just nicer ways to do it.
If I understand you correctly, the measurements array represents past measurements of a specific user.
If that is the case- you're not looking for a singleton at all.
remember that a singleton is a single value PER APPLICATION, and what you're looking for here is a single value PER USER.
Don Roby is absolutely right- Measurements is probably a property of the User class. for example (I'm using c# notation, but you get the hang of it...):
public class User
{
public string Name {get; set;}
public int Id {get; set;}
public Measurement[] Measurements {get; set;} //one array per-user...
}

Pattern for Ownership and References Between Multiple Controllers and Semi-Shared Objects?

For example, I have window (non-document model) - it has a controller associated with it. Within this window, I have a list and an add button. Clicking the add button brings up another "detail" window / dialog (with an associated controller) that allows the user to enter the detail information, click ok, and then have the item propagated back to the original window's list. Obviously, I would have an underlying model object that holds a collection of these entities (let's call the singular entity an Entity for reference).
Conceivably, I have just one main window, so I would likely have only one collection of entities. I could stash it in the main window's controller – but then how do I pass it to the detail window? I mean, I probably don't want to be passing this collection around - difficult to read / maintain / multithread. I could pass a reference to the parent controller and use it to access the collection, but that seems to smell as well. I could stash it in the appDelegate and then access it as a "global" variable via [[NSApplication sharedApplication] delegate] - that seems a little excessive, considering an app delegate doesn't really have anything to do with the model. Another global variable style could be an option - I could make the Entity class have a singleton factory for the collection and class methods to access the collection. This seems like a bigger abuse than the appDelegate - especially considering the Entity object and the collection of said entities are two separate concerns. I could create an EntityCollection class that has a singleton factory method and then object methods for interaction with the collection (or split into a true factory class and collection class for a little bit more OO goodness and easy replacement for test objects). If I was using the NSDocument model, I guess I could stash it there, but that's not much different than stashing it in the application delegate (although the NSDocument itself does seemingly represent the model in some fashion).
I've spent quite a bit of time lately on the server side, so I haven't had to deal with the client-side much, and when I have, I just brute forced a solution. In the end, there are a billion ways to skin this cat, and it just seems like none of them are terribly clean or pretty. What is the generally accepted Cocoa programmer's way of doing this? Or, better yet, what is the optimum way to do this?
I think your conceptual problem is that you're thinking of the interface as the core of the application and the data model as something you have to find a place to cram somewhere.
This is backwards. The data model is the core of the program and everything else is grafted onto the data model. The model should encapsulate all the logical operations that can be performed on the data. An interface, GUI or otherwise, merely sends messages to the data model requesting certain actions.
Starting with this concept, it's easy to see that having the data model universally accessible is not sloppy design. Since the model contains all the logic for altering the data, you can have an arbitrarily large number of interfaces accessing it without the data becoming muddled or code complicated because the model changes the data only according to its own internal rules.
The best way to accomplish universal access is to create a singleton producing class and then put the header for the class in the application prefix headers. That way, any object in the app can access the data model.
Edit01:
Let me clarify the important difference between a naked global variable and a globally accessible class encapsulated data model.
Historically, we viewed global variables as bad design because they were just raw variables. Any part of the code could alter them at will. This nakedness led to obvious problems has you had to continuously guard against some stray fragment of code altering the global and then bringing the app down.
However, in a class based global, the global variable is encapsulated and protected by the logic implemented by the encapsulating class. This encapsulation means that while any stray fragment of code may attempt to alter the global variable inside the class, it can only do so if the encapsulating class permits the alteration. The automatic validation reduces the complexity of the code because all the validation logic resides in one single class instead of being spread out all over the app in any random place that data might be manipulated.
Instead of creating a weak point as in the case of a naked global variable, you create strong and universal validation and management of the data. If you find a problem with the data management, you only have to fix it in one place. Once you have a properly configured data model, the rest of the app becomes ridiculously easy to write.
My initial reaction would be to use a "modal delegate," a lot like NSAlerts do. You'd create your detail window by passing a reference to a delegate, which the detail window would message when it is done creating the object. The delegate—which would probably be the controller for the main window—could then handle the "done editing" message and add the object to the collection. I'd tend to not want to pass the collection around directly.
I support the EntityCollection class. If you have a list of objects, that list should be managed outside a specific controller, in my opinion.
I use the singleton method where the class itself manages it's own collections, setup and teardown. I find this separates the database/storage functionality from the controllers and keeps things clean. It's nice and easy to just call [Object objects] and have it return a reference to my list of objects.

Abstract design / patterns question

I had a bunch of objects which were responsible for their own construction (get properties from network message, then build). By construction I mean setting frame sizes, colours, that sort of thing, not literal object construction.
The code got really bloated and messy when I started adding conditions to control the building algorithm, so I decided to separate the algorithm to into a "Builder" class, which essentially gets the properties of the object, works out what needs to be done and then applies the changes to the object.
The advantage to having the builder algorithm separate is that I can wrap/decorate it, or override it completely. The object itself doesn't need to worry about how it is built, it just creates a builder and 'decorates' the builder with extra the functionality that it needs to get the job done.
I am quite happy with this approach except for one thing... Because my Builder does not inherit from the object itself (object is large and I want run-time customisation), I have to expose a lot of internal properties of the object.
It's like employing a builder to rebuild your house. He isn't a house himself but he needs access to the internal details, he can't do anything by looking through the windows. I don't want to open my house up to everyone, just the builder.
I know objects are supposed to look after themselves, and in an ideal world my object (house) would build itself, but I am refactoring the build portion of this object only, and I need a way to apply building algorithms dynamically, and I hate opening up my objects with getters and setters just for the sake of the Builder.
I should mention I'm working in Obj-C++ so lack friend classes or internal classes. If the explanation was too abstract I'd be happy to clarify with something a little more concrete. Mostly just looking for ideas or advice about what to do in this kind of situation.
Cheers folks,
Sam
EDIT: is it a good approach to declare a
interface House(StuffTheBuilderNeedsAccessTo)
category inside Builder.h ? That way I suppose I could declare the properties the builder needs and put synthesizers inside House.mm. Nobody would have access to the properties unless they included the Builder header....
That's all I can think of!
I would suggest using Factory pattern to build the object.
You can search for "Factory" on SO and you'll a get a no. of questions related to it.
Also see the Builder pattern.
You might want to consider using a delegate. Add a delegate method (and a protocol for the supported methods) to your class. The objects of the Builder class can be used as delegates.
The delegate can implement methods like calculateFrameSize (which returns a frame size) etc. The returned value of the delegate can be stored as an ivar. This way the implementation details of your class remain hidden. You are just outsourcing part the logic.
There is in fact a design pattern called, suitable enough, Builder which does tries to solve the problem with creating different configurations for a certain class. Check that out. Maybe it can give you some ideas?
But the underlying problem is still there; the builder needs to have access to the properties of the object it is building.
I don't know Obj-C++, so I don't know if this is possible, but this sounds like a problem for Categories. Expose only the necessary methods to your house in the declaration of the house itself, create a category that contains all the private methods you want to keep hidden.
What about the other way around, using multiple inheritance, so your class is also a Builder? That would mean that the bulk of the algorithms could be in the base class, and be extended to fit the neads of you specific House. It is not very beautiful, but it should let you abstract most of the functionality.