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.
Related
Im trying to understand the high level implementation of protocols without delegates in Apple frameworks. When a subClass conforms to and implements a protocol method, how is that method called? Lets consider the NSCoder protocol methods (encodeWithCoder: and initWithCoder:) for instance.
Without delegates, could you provide any uses cases for protocols (other than achieving polymorphism? I see that some methods could be abstracted away from base classes and grouped into an interfaces but without any implementation (as mixins for instance), what is the significant use?
First, protocol methods are not special in any way. They, like every other Objective-C method, gets called by a message sent to an object. There's nothing special about that part of things. Protocols are basically just a hint to the compiler, though you can query whether an object conforms to one at runtime and make decisions based on that.
You can verify this by implementing a protocol method (or the entire protocol) without declaring that fact in a classes' interface, and call the function on an instance of that object after casting it to be id<YourProtocol>, and it will work.
You can (and sometimes should) call NSCoding methods yourself -- you may decide that you want to persist objects to the disk, and that this is the best way to do it.
NSCoding is actually a great example of why protocols are still useful even though they do not provide any implementation -- the implementation of initWithCoder: and encodeWithCoder: will be different for every class that implements them -- there is no sense in providing an implementation.
Building on that, consider the datasource property of a UICollectionView; as there is no multiple inheritance in Objective-C, it would be undesirable for the datasource to be a class itself, as that would prevent you from using a UIViewController as the data source, and force you to make a whole new class for that express purpose.
Protocols can also be used to implement multiple inheritance in a type safe way without redeclaring the interface of the giver in the inheritor. If the entire interface of the class being inherited from is a protocol, then the inheritor can simply conform to that protocol as well.
Objective-C does provide mixins in the form of Categories, which can implement protocols on existing classes.
For a full throated defense of protocols (in Swift), see the Protocol-Oriented Programming WWWDC 2015 talk.
Taking the example of the NSCoding Protocol, the two required methods in the protocol, basically implement the steps an object should perform to encode itself to be archived. It also implements the initWithCoder to recreate the object from the archive.
Lets say you create a custom object, only your object knows which properties it needs to archive.
When you call a method to archive your custom object, the method call ultimately flow to your encodeWithCoder or initWithCoder to take action specific to your class.
***** Updated ****
Looking at this with an example :
Lets say our data structure looks like this
someArray = [String,CustomObject,aDictionary]
When we want to archive someArray, we call the archiveRootObject method on it. Now inorder for someArray to archive itself, it needs all its contained items to inturn archive themselves. The Array simply instructs the sub items to archiver themselves calling the encodeWithCoder method on them.
By adopting and conforming to the NSCoding protocol, you are just confirming to the root array that Yes, I know how to archive and unarchive myself.
Hope this helps.
I've read more than once that the Delegate Pattern used in Cocoa is an implementation of the Adaptern Pattern (http://en.wikipedia.org/wiki/Adapter_pattern).
They share the same intent, which is: let two objects with incompatible interfaces to work with each other.
The delegate object is the Adapter, because it adopts a protocol required by a client, the class that requires the protocol and has a weak reference to a delegate is the Client (so, this would be a class of the Cocoa framework).
My question is: who is the Adaptee? The delegate pattern doesn't wrap itself around any object, from what I've seen, who is the object that needs to be adapted?
Delegates are not really an example of the Adapter pattern. Protocols would be closer, but the best way to implement the Adapter pattern in Objective C is to create a new object that contains the object you want to adapt and uses it to serve a client.
Categories are another way of implementing the Adapter pattern, but they have some limitations. You can't override the implementation of existing methods in a category, and you can't add additional instance variables to a class with a category. However you can implement properties using associated objects and you can also add new instance methods.
You can also use multiple inheritance to implement the Adapter pattern in languages like C++ that offer it, but Objective-C does not support multiple inheritance.
A simple example of an Adapter using a category that I use in my projects is as follows:
Interface Builder (IB) includes a feature called "User Defined Runtime Attributes" that lets you set properties on your custom interface objects using Key Value Coding (KVC). It lets you specify a limited number of data types (ints, floats, bools, points, rects, UIColors, and a few others.)
You can use User Defined Runtime Attributes to set the border width and corner radius on a view's layer, and you SHOULD be able to use it to change the layer's border color or background color. However, layer colors are specified as CGColors, and UIViews use UIColors. Since IB only accepts UIColors in a User Defined Runtime Attribute, it doesn't work.
To fix this, I created a category of CALayer called CALayer+setUIColor. It has 2 methods, setBorderUIColor and setBackgroundUIColor. Those methods are very simple. They take UIColors as input, and simply convert the UIColor to a CGColor and set the layer's border color or background color.
You can see an early version of this category in my github project KeyframeViewAnimations.
I'd say that is a completely wrong view of the Cocoa delegate pattern.
The object needing a delegate is intentionally left incomplete. But instead of having an abstract class and adding the required functionality through subclassing, we add the required functionality by providing another object, the delegate.
Nowadays people will more and more switch from using delegate objects to providing the required functionality by passing one or more blocks instead.
I've found a solution in the official documentation, as I suspected there is no adaptee:
https://developer.apple.com/legacy/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW5
Delegation is not a strict implementation of the Decorator pattern.
The host (delegating) object does not wrap an instance of the class it
wants to extend; indeed, it’s the other way around, in that the
delegate is specializing the behavior of the delegating framework
class. There is no sharing of interface either, other than the
delegation methods declared by the framework class.
Delegation in Cocoa is also part of the Template Method pattern
(Template Method).
Source: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW19
The DELEGATE object is Adapter because:
It uses special protocol of special object and wrap it to itself special protocol.
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 understand a class is actually an object / typedef of struct (objc_class*).
Each class has a "backing" meta class, which in turns has a isa pointer pointing to the meta class of NSObject.
And NSObjectbasically has a isa pointer pointing back to itself.
And we could get a hold of the meta class via this line:
objc_getMetaClass("<CLASS_NAME>");
I hope my understanding of meta class is not off here so far (please correct me if it is).
My questions are:
1.)
When would we need to deal with meta class? Could you please cite an
example / a scenario in code when we might need to?
2.)
Background:
I was thinking freely about third party libraries and how they are structured.
Usually they provide you with a class method and return you a class and all other methods are private / "hidden". And most of the time, while they can be subclassed but since we do not know the init method, it would be of no use to subclass.
And suddenly I began thinking about Objective-C Category and thus leading me to think of Objective-C meta class.
And this leads to my question #2:
Is it possible to break this structure by making use of Objective-C
Category and / or with the use of meta class (by grabbing a hold of
it and insert a class method straight there in the meta class)? Or
even look up the name of their instance methods that are private?
My intention here is not to "break" anything, I am just very curious as to how "unbreakable" these third party libraries are structured and if their structures cannot be "broken" via the use of Category and Meta Class.
#Leo Natan:
1.)
What is method_*()?
2.)
For the love of Objective-C Runtime:
Could you cite an example implementation-swizzling an instance method, let say,
(I am not sure if this method is a good example, for we could override it in the first place)
NSArray's -count instance method (let’s make it so that it returns always count 100, for example)
3.)
So in theory all classes (including all third party libraries) can be break (broken)? Other words, there is no way to create a „call-only-this-class-method-or-you-cannot-use-me“ API / library?
Thanks a lot.
The meta class is useful when wishing to view, add or modify class methods and class-level information.
For example,
IMP myIMP = imp_implementationWithBlock(^(id _self, NSString *string) {
NSLog(#"Hello %#", string);
});
Class cls = objc_getMetaClass("NSString");
class_addMethod(cls, #selector(test:), myIMP, "v#:#");
[NSString test:#"lala"];
To get instance methods, you use class_copyMethodList() on the class returned by class method on an object or NSClassFromString(). You will get an array of all the instance methods defined by the class (but not of its superclass!). You can then use the various method_*() methods to retrieve information and possibly even modify these methods (like implementation swizzling).
You can call class_copyMethodList() on the meta class to get all the class methods defined.
To address your "Leo" questions,
1.
Please read the Objective C Runtime Reference. You can find a section of method_ functions dealing with Method structs.
2.
See tutorial on implementation swizzling.
3.
Using Objective C, everything is available to the runtime. It goes without saying, that with great power comes great responsibility. The Objective C runtime is very powerful. These swizzles are very dangerous and usually not recommended.
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.