subclassing NSDictionary like so: #implementation NSDictionary (weather) - ios

I am looking at the Ray Wenderlich AFNetworking tutorial, and I have come across a way of subclassing NSDictionary that I have not seen before:
first:
#implementation NSDictionary (weather)
then in another file:
#implementation NSDictionary (weather_package)
This seems to just "work" in another file where it's included. What's most puzzling is that the NSDictionary defined in a class that uses these seems to match the "weather_package" version and within that container the "weather" version.
Can someone point me to the name of what's going on here? I am not entirely clear on how this works from reviewing the code, particularly how the compiler decides what to apply where since no explicit reference is made to these files apart from including them in the header.
Thank you for any help.

This is not subclassing. This is extending the class using categories. This is used to bring new functionality into existing classes without subclassing them.
A category can be declared for any class, even if you don’t have the original implementation source code (such as for standard Cocoa or Cocoa Touch classes). Any methods that you declare in a category will be available to all instances of the original class, as well as any subclasses of the original class. At runtime, there’s no difference between a method added by a category and one that is implemented by the original class.
A category can be defined like
#interface ClassName (CategoryName)
#end
#implementation ClassName (CategoryName)
#end
For more information read https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW1

It's not subclassing, it's more extending existing implementation with new methods, so called categories:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html

Related

Objective C: Declaring a selector but implementing it in objects category

I have a framework in obj-c which is included by other modules. I want to allow the modules which are going to include it to provide their own implementation for certain methods.
I can't use subclassing because of some issues around serializing these objects. So, have to rely on using category.
I am thinking of declaring a method/selector for the object and then modules will define the category and implement that method. Something like below:
Framework will declare interface like below:
#interface framework:NSObject
- (void)methodToBeImplemented;
#end
#implementation framework()
- (void)invokeClientDefinedMethod
{
if([self respondsToSelector:#(methodToBeImplemented)]) {
[self methodToBeImplemented];
}
}
//Module-1 will link against this framework and define the category
#implementation framework(methodImplementor)
- (void)methodToBeImplemented
{
...
}
#end
Can I choose not to implement methodToBeImplemented at all in framework and implementation to be provided by the modules themselves.
I know that I can do it performSelector route. But I cringe to do so because I want to send pointers to my method which is not really possible with performSelector
If possible, I would highly recommend using a delegate pattern for your object so that callers can pass a delegate that conforms to a protocol rather than directly extending the class. That's the normal way to implement this kind of system. But if there's a particular reason a delegate is not possible, you can build what you're describing.
What you're looking for is an informal protocol, which is how almost all protocols were handled prior to the introduction of #optional.
What you want to do is define a category on your class in your public header:
#interface Framework (OverridePoints)
- (void)methodToBeImplemented
#end
This declares that such a method may exist, but it does not enforce its actually being implemented. The key is having a name in the parentheses. This can be anything (I used "OverridePoints" here), but it cannot be empty since that would be an extension instead of a category.
Once you have that, then the rest of your ideas work. You can test for respondsToSelector:, and the consumer can implement (or not implement) the category methods just as you describe.
The one danger is that there is nothing preventing multiple parts of the program implementing the same method in categories. That is undefined behavior, but the compiler will not catch it for you.

Without exposing the interface in the public header of framework can I pass a custom object to the client application?

I am working with a objective-C framework.
I have a public framework header "MyPublicHeader.h" exposed to the client application. I have a custom class in the project,
//MyCustomClass.h file
#interface MyCustomClass.h
- (NSString *) methodA;
#end
//MyCustomClass.m file
#inplementation
- (NSString *) methodA {
}
#end
If I want the client to instantiate the class I have to make it as public framework header. I want to hide the interface as a curiosity, is there any way to do it???
First know that nothing can be truely hidden in Objective-C due to the nature of dynamic dispatch and the features in the runtime which allow discovery of methods etc.
That said there are a number of ways to do this, a couple:
Use a subclass. Declare a superclass and publish its interface as part of your framework. Make your class a subclass of this and publish its interface only within the framework. You define one or more init methods in the superclass which return and instance of the subclass, and if you want to expose any further API define it in the superclass with dummy (or faulting) implementations and less the subclass override etc. This approach is similar to the model used for classes like NSString.
A .h file is just text and you can exploit this: make two .h files, say MyCustomClass.h and InternalMyCustomClass.h. In the first just declare the interface with no members, or the API you wish to make public, and publish that to users of the framework. In the second declare the real interface used within the framework. You must make sure to keep all three of the files (2 .h, .m) in sync. This approach would be call little naughty by some, "here be dragons" by others, or "needs must" by yet others...
You might also like to look into "class extensions" which are related to categories.
Hope that satiates your curiosity a little, and keep up with the curiosity its good (except for cats)!
You could create an empty wrapper class which only holds a reference to your MyCustomClass object.
When they create this object you secretly instantiate an object of your MyCustomClass inside and extract it when they pass you an object of the wrapper class.
Not sure if this is exactly what you want to achieve, but could be a workaround.

Undeclared Methods vs Categories in Objective-C

Imagine I have define a class MyClass as follows:
The class interface file:
#import <Foundation/Foundation.h>
#interface MyClass : NSObject
#property (nonatomic) NSString *myProperty;
- (void)myPublicMethod;
#end
The class implementation file using categories:
#import "MyClass.h"
#interface MyClass (MyCategory)
- (void)myPrivateMethod;
#end
#implementation MyClass
- (void)myPublicMethod {
NSLog(#"myPublicMethod was called!");
[self myPrivateMethod];
}
- (void)myPrivateMethod {
NSLog(#"myPrivateMethod was called!");
}
#end
An alternative class implementation file NOT using categories:
#import "MyClass.h"
# implementation MyClass
- (void)myPublicMethod {
NSLog(#"myPublicMethod was called!");
[self myPrivateMethod];
}
- (void)myPrivateMethod {
NSLog(#"myPrivateMethod was called!");
}
#end
Was hoping someone could explain the difference between the two implementation file approaches.
Is it the case that using categories means the "private" methods are inherited by any subclasses of MyClass and not using categories means the "private" methods are not inherited by any subclasses?
All methods that exist on a class are always inherited and are callable by anyone regardless of how you declare them. The main difference is whether anybody knows about them. There was also a historic need to declare things before use which leads to internal forward declarations in older and old-style code.
A category is used to add methods to an existing class. A common use is to extend the functionality of one of the existing classes. For example you might implement:
#interface NSURL (HTTPQueryParameters)
- (NSDictionary *)httpQueryParameters;
#end
So from then on you've given NSURL itself the knowledge required to parse HTTP protocol query parameters. It's often the correct factoring to add functionality directly to classes you don't have the source for.
Objective-C used to follow the C rule that methods had knowledge only of those methods that had preceded them within the compilation unit. So to be able to call a method that appeared later in the source file you'd need a forward declaration. If you didn't want to publish that method for the world to see you could achieve that with a category or a class extension (which for this purpose is just an unnamed category).
Nowadays Objective-C methods can call any method that is defined anywhere within the compilation unit, including subsequently in the same source file. It's therefore now normal not to collect up your unpublished methods into a category or an extension just for the benefit of the compiler.
That leaves categories for:
adding functionality to existing classes; and
segmenting your classes if they become very large;
Class extensions are now primarily for:
declaring #propertys without publishing them.
In Objective-C any method call can be sent to any object — objects are dynamically typed. So there's a mapping table in memory at runtime for every class from method name to implementation. The lookup process is to see whether the method is implemented in the class dispatched to. If not then dispatch to the superclass. An exception will be raised if the runtime runs out of superclasses.
The declaration of the method in a category #interface only serves to expose the method to users of the class, including -- as you mentioned in your comment -- subclasses.
(It would be much more usual to use a class extension (sometimes called an "anonymous category") declare a method that you're defining in the main implementation block. Actually, I'm not 100% sure what the interaction is between your category declaration and the main block definition -- I wouldn't have been surprised if it didn't compile, but it does.)
Thus, the only difference between your two examples is that the declaration allows you to create a private header in a situation where you want your own subclasses to access this method, but have framework users who you want to restrict.

Static variable is nil - Objective C

Hi I have just now learned Objective C and I am doing some exercises to practice myself. I have two classes here one "main class" and one "sub class". what i needed is to get all the instances of my "main class" and put it in an array. I also wanted to use it in my "subclass". Below i give a small example.
#interface mainClass : NSObject
static NSArray *instanceObj;
#end
#implementation mainClass
//Here i used the designated initializer to initialize and add the instance to the Array
#end
#interface subClass:mainClass
#end
#implementation subClass
//Here i want to use the Array to get instances of mainClass.
#end
If i do as the above example, I get a warning stating that the static array is not used and when getting data from Array its nil. Also I tried declaring the static array in implementation file of "main Class", But i cannot use the Array in "Sub Class". Kindly provide me a solution.
Friends, Although this question is not that important, It may help me understand things. So please help me understand the concept and I may delete this question completely. Thank you
A couple of issues:
Move the static outside of the #interface, and into the .m file above the #implementation.
You obviously would need to make that NSMutableArray, not an NSArray.
Be forewarned that by adding objects to that array, that establishes a strong reference to those objects, and they won't be released until you remove them from the array.
As an aside, you might also want to conform to Cocoa naming conventions, using MainClass and SubClass rather than mainClass and subClass. Better, use meaningful names.

What does the text inside parentheses in #interface and #implementation directives mean?

I've got a very basic question about some sample code from Apple. In the .m file, the class declarations look like this:
#interface MyMovieViewController (OverlayView)
[...]
#end
#interface MyMovieViewController (ViewController)
[...]
#end
#implementation MyMovieViewController(ViewController)
[...]
#end
#implementation MyMovieViewController (OverlayView)
[...]
#end
#implementation MyMovieViewController
[...]
#end
Full code here.
It seems like the stuff inside parentheses ("OverlayView" and "ViewController") are just there to help break up the code and make it more readable, but don't actually impact the execution of the code. But I don't want to be misunderstanding something important, so I thought I'd check to make sure.
Is my understanding right? Thanks!
Those are called Categories and allow you to add further functionality to your classes.
A category allows you to add methods to an existing class—even to one for which you do not have the source. Categories are a powerful feature that allows you to extend the functionality of existing classes without subclassing. Using categories, you can also distribute the implementation of your own classes among several files. Class extensions are similar, but allow additional required APIs to be declared for a class in locations other than within the primary class #interface block.
From the Apple docs on Categories and Extensions.
Those are "categories".
With those you can extend any objective-C class by adding methods, which will apply to all the objects of the class.
More detailed article here: http://macdevelopertips.com/objective-c/objective-c-categories.html

Resources