I just want to make sure I'm using class methods correctly.
By way of example, let's say I'm creating a game that involves a single map and individual tiles on that map (for instance, 16 x 16 tiles).
Each tile can consist of either a building, tree, road, etc - and this can change throughout the game.
Would I be correct in setting up a Map class with a class method to initialise the map, simply because there will only be one map and I would have no need to instantiate more than one?
Would I also be correct in setting up a Tile class with instance methods to initialise the tiles, because there would be 256 tiles each with their own properties?
Struggling to get my head around it all, any advice would be greatly appreciated.
There are multiple patterns for dealing with this, but basically it boils down to the Map class being a singleton. Some prefer to enforce the singleton-ness of the class by disallowing the creation of multiple instances (for example, by hiding the constructor, or making the constructor throw an exception, etc). In other cases it just suffices to document the Map class as being a singleton and use it as such.
A simple way of dealing with singletons in Objective-C is to create a class method for instantiating it, i.e.:
static Map* defaultMap = nil;
+ (Map*) defaultMap {
if(!defaultMap) defaultMap = [[Map alloc] init];
return defaultMap;
}
Using class methods for the map is probably not such a good idea, just like global variables is something that should usually be reduced to a minimum (though the example above is really a global variable, it will be a lot easier to refactor your code once you have a need for multiple maps).
Map class can be implemented as singleton pattern. Or any other way that limits it to only 1 shared instance.
Related
I'm currently working on a game using swift and spritekit. I have a class called Utilities that has a bunch of generic functions that get used around the game. Currently I create a new instance of the Utilities class in my single game scene, and then pass the references though to other classes like so
self.util = Utilities()
self.player = Player(util: self.util)
self.monster = Monster(util: self.util)
I'm doing this so that i only create one instance of the class, but the more i go on the more just want to make a new instance of utilities in each class i need it in. Is there a downside to this? Is it more efficient to just have the one instance created and pass it around or will it not make a difference if i have say 5 or 6 instances?
Ideally you shouldn't need to instantiate your Utilities class. You can write public functions in it and call those methods from where ever you like.
If you need to instantiate your class and would like to keep a single instance, you should go for singleton. You can create a singleton like
class Utilities {
static let sharedInstance = Utilities()
}
And you can get the instance by calling Utilities.sharedInstance
If the Utilities instance does not hold any specific state, then you probably don't need a class at all. Just define your functions as public global functions.
Swift is not Java. Functions can stand on their own. They don't need to be attached to a class.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html
I was looking at the Map Kit Framework documentation and it got me wondering why some classes are referred as objects. I know his may be a lack of knowledge on OOP in general but I need to ask.
For instance, this is how they are describing the MKDirections class in the MapKit Framework Reference.
An MKDirections object provides you with route-based directions data from Apple servers.
And this is how they describe the MKDirectionsRequest class.
The MKDirectionsRequest class is used by apps that work with turn-based directions.
Is there a reason why they couldn’t describe the MKDirections class in a similar fasion as the MKDirectionsRequest class? In other words something like...
The MKDirections class is used to provide you with route-based directions data from Apple servers.
My main confusion comes because I was under the impression that you create an object as soon as you instantiate a class. In other words we know that an object will be created when using the MKDirections class so, why not call it class.
Sorry if my question doesn't make any sense but I’m curious if there is something I should be aware when reading the documentation and I come across these two different references, is there something special on the classes they describe as objects?
Thanks
So in OOP classes are objects. The class objects are like blueprints, or printing plates, for instance objects which are created in the run of the program and actually perform the methods which are called. When a program loads, all of the class objects are initialized from the NSObject inheritance as a framework, which then allows you to create instance objects of all the basic types (or custom types if they're loading) during the run of the program. So the class objects are templates. But in filling out, say, a paper form, you don't want to fill out the template itself, you create a copy of it which you then fill out, leaving the template itself unchanged and available for further copying. This is the essential distinction between a class object and an instance of that object.
The difference between MKDirections and MKDirectionsRequest has to do with object inheritance. MKDirectionsRequest is what's called a subclass of MKDirections. The subclass object and its instances contains all of the properties and can perform all of the methods of its superclass, but can perform additional methods or properties outlined in its class profile. So an MKDirectionsRequest instance object is of the class MKDirectionsRequest which inherits from the MKDirections class.
Matt Neuberg's Programming iOS 6 is available for free online (since it's outdated), but his early chapters on C-language inheritance and OOP orientation are still valid and very helpful. Here's a link to the section on Classes and Instances:
http://www.apeth.com/iOSBook/ch02.html#_classes_and_instances
You're right that the object is created by instantiating the class. Maybe the distinction is due to the fact that the MKDirectionsRequest class has a class method isDirectionsRequestURL:. MKDirections only has instance methods.
One possible reason for the difference -- and I'm stretching here -- is that one of those classes has a class method while the other only has object/instance methods. It is possible to use a MKDirectionsRequest class without creating an instance. (+ (BOOL)isDirectionsRequestURL:(NSURL *)url)
It's more likely, though, to be a style difference. If you assume that apps usually use classes by creating an instance of them first, the "class" description is functionally equivalent to the "object" one.
I need to write some methods in a non ARC project in Xcode. I have to implement a NSXMutableDictionary class, a mutable dictionary that can contain up to four key-value pairs. The methods I have to implement are following:
- (void)setObject:(NSObject *)theObject forKey:(NSObject *)theKey;
- (void)removeObjectForKey:(NSObject *)theKey;
I have no clue how to do it, any help would be highly appreciated.
Thanks.
It's not a lot to go on.
But with what you provided, it's best to subclass NSObject and have a private property that is an NSMutableDictionary.
That allows you to implement all of the same methods of NSMutableDictionary just by declaring them, then in your implementation of each you just call the same method on your actual dictionary property.
The difference you add is a check to see if you already have 4 KVPs or not. And any additional methods you need or want.
This is the design pattern of Composition.
I agree with #uchuugaka. Create an object that has an NSMutableDictionary inside it. (This is a "has-a" relationship rather than an "is-a" relationship)
The NSDictionary family is what's known as a "class cluster". A class cluster is a public interface that's actually implemented by a set of private classes that you don't see.
Subclassing a class that is part of a class cluster is tricky, and not for beginners. There are a whole set of primitive methods you have to implement in order to create a subclass of a class cluster. Plus, your custom subclass will likely not preform as well as the original class because you won't adapt to different use-cases like the class cluster does.
I have a class, User, that has an NSMutableArray that stores custom NSObjects. I only want one of these to ever be instantiated throughout the entire app, and I would like to be able to call methods on it in each ViewController for getting and setting. My problem is that I don't know how to call the methods so they apply to this one instance, instead of creating a new one each time. I'm new to objective-c, so the learning curve makes me feel I'm missing something a bit obvious. I've been working on this all day and am at a wit's end. Is there a good solution to my dilemma? Should I use a singleton class?
(If it helps, the class User is basically a class that stores a to-do list for each user that uses my app. The custom NSObjects are to-do items. There's probably a better storage method that should be used here, but I'm not sure what it is.)
RandomPleb it sounds like what you're looking for is a Singleton. http://en.wikipedia.org/wiki/Singleton_pattern. I also think this question has been answered before so search around on SO.
Laymen's terms; you create a static reference to the class that you only want one of inside that class, then make a static method in the following way:
//call this from classes that want to modify it
public static getsharedinstance()
{
if(the static instance of this class does not exist){
instantiate instance;
}
return this classes static instance..
}
Hope this helps (and if this is wrong, I hope someone can correct me)
Also in regards to your storing objects, I think NSMutableArray is fine unless it is a very big persistent list where each task has many properties in which case maybe using CoreData would be better.
Fenix
So I'm getting myself into a confusion over where my data's going and where it's stored in my application. It's not a specific question so hopefully someone can provide a generalised answer.
I need to pass some data around between a few UIViewController instances, and I'm currently doing that with a singleton object called my dataManager. This class has one method, a class method, called + (LCDataManager *) sharedDataManager, and that method basically checks if whether the sharedDataManager already exists, if so, return it, if not, create it and set up its variables. This means that I can refer to that class anywhere I like, access and modify its variables anywhere I like, from across multiple classes.
First question: is this the correct / best / most appropriate means of passing data around like this? I'm hoping it obeys MVC, it feels like it does, and I hope I'm right.
Second question: what if I want to put an instance method in that class, and call it from within the class method? Let's say my sharedDataManager needs to call a method to grab some objects one of its variables (an array), and put them in another array, then send that back out again. I can't do that, can I? What's the way around that? If I make an instance of that class (rather than using the shared instance), I lose the ability to use that instance across multiple viewControllers.
I'm hideously confused, and it seems like it's not the problem I'm making it. Appreciate any guidance, and preferably not that "Read the Apple documentation" stuff – they write as if you already know what you're doing, and frankly I don't yet.
First question: is this the correct / best / most appropriate means of passing data around like this? I'm hoping it obeys MVC, it feels like it does, and I hope I'm right.
Your design is perfectly MVC compliant.
Second question: what if I want to put an instance method in that class, and call it from within the class method?
you can surely define an instance method and call it like this:
[[MyModelClass sharedModel] myInstanceMethod];
indeed, [MyModelClass sharedModel] will give you an instance of MyModelClass (which should be guaranted to be unique being it a singleton).
If you want to call the instance method from the sharedModel class method, you could also do that, because sharedModel owns a reference to your singleton, so it can send messages to it.
is this the correct / best / most appropriate means of passing data around like this?
There's nothing wrong with only having a single instance of LCDataManager, but using the Singleton pattern has potential problems. An alternative is to just initialize one LCDataManger and to pass it around to wherever it's needed.
what if I want to put an instance method in that class, and call it from within the class method?
The accessor + (LCDataManager *) sharedDataManager should only return the instance. I guess what you want is something like
+ (LCDataManager *)preparedDataManager {
LCDataManager *shared = [self sharedDataManager];
[shared doSomeInstanceMagic];
return shared;
}
- (void)doSomeInstanceMagic {
// magic!
// grab some objects one of its variables (an array),
// and put them in another array
}
Matthijs Hollemans has an excellent three-part tutorial on his blog about the correct way to make your view controllers talk to each other:
Part 1
Part 2
Part 3
there is no problem with this development architecture, and it is the must used (I think) in the iOS development. In the book IOS Programming: The Big Nerd Ranch Guide they call it Model View Controller Store.
Regarding your second question, yes, you can declare instance methods and call then from your sharedDataManager. What is not usual is creating other instances of a singleton class, but it is possible.