I have spent a few days learning and writing NSCoding and finally got it working. However, it took very long to archive and unarchive the (quite complex) object graph, which is unacceptable. After searching the internet for some time, I think the better way is to use core data.
Do you recommend that 1) I should rewrite all my classes as subclasses of NSManagedObject or 2) should I create an instance variable of NSManagedObject in each of my class so that any changes to the class also updates its core data representation? Doing either way will need significant changes to the exiting classes and I think I have to update lots of unit test cases as well if it changes the way the classes are initialized.
What do you recommend? I really don't want to head to the wrong approach again...
Thanks!
I would recommend 1), if you use Core Data.
2) doesn't make much sense. For example, say A* a1 and A* a2 refer to the same B* b. If A and B are subclasses of NSManagedObject, this relationship can be easily saved to and then be retrieved from the file. But if A and B have NSManagedObject instances as ivars, how do you maintain this relationship that two As refer to one B? You will be forced to write a whole lot of glue codes, which are basically provided by the Core Data APIs.
If you decide to use Core Data, one very important advice I can give is to read Apple's documentations very, very carefully from the start to the finish, and to resist the urge to write codes from the day one. Core Data is a rather big set of API, and a good grasp of the whole structure before starting to write codes will save you many days afterwards.
Related
This is similar to a question I asked before, but now that I've come much further along I still have a question about "proper" subclassing of NSManagedObject as I was told last night that it's a "bad idea" to put lots of non-persisted properties and ivars inside one. Currently I have TONS of code inside my NSManagedObject, and Apple's docs don't really address the "rightness" of that. FYI: the code works, but I'm asking if there are pitfalls ahead, or if there are obvious improvements to doing it another way.
My "object" is a continuously growing array of incoming data, the properties/ivars that track the progress of the analysis of that data, and the processed data (output). All of this is stored in memory because it grows huge, very quickly, and would not be possible to re-generate/re-analyze continuously. The NSManagedObject properties that are actually persisted are just the raw data (regularly saved, as Core Data doesn't support NSMutableData), a few basic properties and 2 relationships to other NSManagedObjects (1 being a user, the other being a set of snapshots of the data). Only one object is being recorded to at any one time, although dozens can be opened for viewing (which may involve further processing at any time).
It's not possible to have the object that inserts the entity (data manager that manages Core Data) have all of the processing logic/variables inside it, as each object necessitates at least a handful of arrays/properties that are used as intermediaries and tracking values for the analysis. And I, personally, think that it sounds silly to create two objects for each object that is being used (the NSManagedObject that is the store, and another object that is the processing/temp store).
Basically, all of the examples I can find using NSManagedObjects have super simple objects that are things like coordinates, address book entries, pictures: stuff that is basically static. In that case I can see having all of the logic that creates/modifies them outside the object. However, my case is not that simple and I have yet to come up with an alternative that doesn't involve duplication.
Any suggestions would be appreciated.
You might use a 'wrapper', that is to say a class with a reference to one of your managed object instances, this wrapper would contain your algorithms and your non persisted algorithms.
I'm working on an iPhone game that has a bunch of monsters. Each monster has a name, up to 4 different attacks, and a few sprites that represent its state. I have a monster class set up and it works really well. I've managed to make two monsters battle and all that jazz and it works. My game though is going to have a predefined group of monsters in it that all have different statistics and I'm kind of struggling to come up with the best way to accomplish this. I have two ideas so far.
Ideas:
Make a class whose only purpose is to define all the monsters available in the game using the Monster class.
Subclass the monster class for each and every monster I need. Even though none of them will really add anything to the monster class.
The benefits for the second method are that it would be easier to make ties between two different monsters (like evolution trees).
What do you guys think would be the best way to do this? I'm leaning towards the second method. Is the another method that I'm missing?
A common pattern for this sort of problem is to create a factory class, which is close to your first idea. You make a single class, called perhaps MonsterFactory, whose job it is to manufacture instances of the Monster class for use elsewhere. If you structure the factory properly, it can even handle the evolution-tree sort of thing well.
An additional benefit of a factory is that it abstracts away the details of storing information about your monsters. For example, you could hardcode the first five or ten monsters' worth of info into the program to test it, but later reimplement the factory to use a database or file on disk for larger volumes of monsters. As long as your factory API remains constant, your Monster class doesn't have to care about those details; it's all in the factory.
Even though none of them will really add anything to the monster class.
The benefits for the second method are that it would be easier to make ties between two different monsters (like evolution trees)
Answered your own question.
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.
When developing how useful is it to create small classes to represent little data structures? For example say as a simplified example, a program is using an array of strings to represent names of something, e.g. cars. Instead of just keeping this array inside a method or class, how useful is it to separate this and make it it own class? This way I am thinking that it can be responsible for itself and more actions can be performed on it - validation, etc. which can all be kept separate. Also, it can be reused easily throughout the system. But then where does it stop, i.e. in the car example, you could then go on to create a car object etc. It really can be never ending can't it?
There are several guidelines I use to determine when I need to refactor a data structure into its own class:
Am I storing a lot of interrelated data? If you find yourself storing a couple of arrays, and manipulating them as a unit, it's probably best to store a single array containing objects.
Are these data structures exposed to other classes? If other classes are directly exposed to the data, it's probably best to encapsulate the data in its own class, which makes it easy to keep the conceptual and actual models separate.
Do I find myself frequently performing operations on the data? It might be fine to store an array of names, but if you start adding methods like validateName and checkName to the wrapping class, it might be a good idea to refactor and place those methods on a Name class itself.
Keep in mind: it's often a lot easier and cleaner to put a decent object model in place up front than to try and graft one on after the fact. You shouldn't do it arbitrarily, but as you're working through your program you should pay attention to when it becomes difficult to control the data structures you have--that's a good sign that you should refactor them, as needed.
It makes sense to do this as soon as you are repeating code to operate on the data structure.
Chris B. makes a great point about interrelated data. See the Extract Class refactoring example.
I am creating a simple application using the MVC design pattern where my model accesses data off the web and makes it available to my controllers for subsequent display.
After a little research I have decided that one method would be to implement my model as a singleton so that I can access it as a shared instance from any of my controllers.
Having said that the more I read about singletons the more I notice people saying there are few situations where a better solution is not possible.
If I don't use a singleton I am confused as to where I might create my model class. I am not over happy about doing it via the appDelegate and it does not seem viable to put it in any of the viewControllers.
any comments or pointers would be much appreciated.
EDIT_001:
TechZen, very much appreciated (fantastic answer as always) can I add one further bit to the question before making it accepted. What are your thoughts on deallocating the singleton when the app exits? I am not sure how important this is as I know quite often that object deallocs are not called on app teardown as they will be cleared when the app exits anyway. Apparently I could register the shared instance with NSApplicationWillTerminateNotification, is that worth doing, just curious?
gary
There is a lot of push back on the use of singletons because they are often abused. Lazy coders either (1) don't put enough functionality in the singleton which results in having logic spread out in other objects like spaghetti or (2) they put in to much functionality such that the singleton becomes the entire program. Lazy coders way to often use singletons instead of doing data validation, object testing and object tracking. People get sick of trying to untangle and maintain lazy singleton use so they try to suppress the use of singletons.
I thoroughly understand the impulse and I myself ritualistically warn against singleton abuse.
However, a data model is one of the few legitimate uses for a singleton. This is especially true in small apps like those which run on mobiles. In the end, you will either use a singleton for your data model or you will attach it to a singleton.
For example, suppose you decide to park your non-singleton data model object in the app delegate. Well, you've done this: dataModel-->appDelegate-->application(singleton). To access it, you would call:
[[[UIApplication sharedApplication (a singleton)] delegate] theDataModelObj];
Even if you pass it around like a token from object to object you will still have to have the dataModel obj begin as the property of a singleton.
When an object really does have to meet the "Highlander" pattern ("There can be only one!") then a singleton is the best choice. In addition to the application object, you have user defaults as a singleton as well as the file manager. Clearly, in all three cases, you want one and only one instance in existence for the entire app. For example, if you had more than one user defaults object, your app would be a train wreck trying to track all the preference settings. If you have more than one file manager, file operations could step on one another.
A properly designed user data model is just a larger version of user defaults. It should be the only object that directly manipulates the user's data. No other object in the app should have that task in the least. That makes the singleton design pattern the best one to use in this particular case.
Singletons are a very powerful tool but just as with a physical tools, the more power they give you, the more opportunities they create for you to cut you head off if you use them carelessly. For this reason, a singleton should seldom be your first choice. There are usually better design patterns to employ.
However, when you really need a singleton, you shouldn't shy away from using them just because the laziness of others has given them a bad rep.
Knowing when and when not to use a powerful and dangerous tool is part of the programmers intuition you develop with experience. You can't go by formula. It is one of those factors that makes good coding an art and the programmer a craftsman.