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

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

Related

Is it possible to use extension methods which are added at implementation file rather than interface file in objective c?

This is header file/Interface file(className.h).
Here printSomething method is declared as an extension. And I'll call it later in main.m
extension.h
#import <Foundation/Foundation.h>
#interface extension_class : NSObject
#end
#interface extension_class () // This is the external method which is added using extension
- (void) printSomething;
#end
This is the Implementation file(className.m). Here printSomething method is defined.
extension.m
#import "extensions.h"
#implementation extension_class
- (void) printSomething
{
NSLog(#"I'm the method defined inside extension class but declared by using extensions");
}
#end
So far everything works fine. Now My question is simple why can't I access that printSomething method if I declare(until now declaration and definition was not done in same file) it in implementation file. As in the below code snippet? (Please compare and observe the changes among above two .h and .m files with below ones to get my point)
extension.h
#import <Foundation/Foundation.h>
#interface extension_class : NSObject
#end
extension.m
#import "extensions.h"
#interface extension_class () // This is the external method which is added using extension
- (void) printSomething;
#end
#implementation extension_class
- (void) printSomething
{
NSLog(#"I'm the method defined inside extension class but declared by using extensions");
}
#end
This is main method which is common in both cases.
main.m
#import "extensions.h"
int main()
{
#autoreleasepool
{
extension_class *object = [[extension_class alloc]init];
[object printSomething];
}
return 'O';
}
So what is point in having extensions in objective C if it doesn't allow us to add methods anywhere we like? or Is there any other method to achieve what I said above?
You're free to define extensions in the .m file. This is incredibly common. Those extensions won't generally be known to importers of the .h file, so they won't easily be callable from other files. That's a good thing. It lets us make "private" extensions, which is very useful and common.
They're not really private. Anything can call anything in ObjC. Outside callers just won't know about the method. But they can declare the method themselves as a category (note the text inside the parentheses) and call it:
OtherClass.m
#import "ExtensionClass.h"
#interface ExtensionClass (ThingsIKnowYouHave)
- (void) printSomething;
#end
...
[extensionClass printSomething];
Or they could of course just call it directly without declaring it (though this can cause ARC problems, so avoid this in modern ObjC):
[(id)extensionClass printSomething];
Or they could call it as a selector (again, this can cause ARC problems; so using the category is best):
[extensionClass performSelector: NSSelectorFromString(#"printSomething")];
There's really not much point to creating extensions in the header file (i.e. "public" extensions). If it's in the header file, you might as well just put it in the interface. The most common use of extensions (basically why they were invented), is so you can define methods inside the implementation file.
Extensions shouldn't be confused with categories, where there is text inside the parentheses. These were created to help organize large classes, and later were used for "informal protocols" before #optional was added. Extensions can add methods directly to the base class. Category interfaces just say "this method might exist." Extension interfaces are formal continuations of the primary interface (the compiler requires that they be implemented).
For more on categories and extensions, see Customizing Existing Classes in the Programming with Objective-C guide. See also Defining Classes in the same guide, which may clear up some confusion I believe you have about header files and interfaces.

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.

Is it possible to reference a .m class in another .m class? Objective C/IOS/Xcode [duplicate]

My question is, that I would know how to use 2 .m files for one objectclass also for one header (.h)
I have a big method with 20000+ lines and I would, that this method stand alone in a .m file and the other methods in the other .m file. I have done it, but I get errors, that the methods aren not in the one .m file. I get a link error, but i can remove the link error if i delete the second .m file.
Is it possible to create 2 .m files for one header ?
If yes pleas tell me how?
I have a big method with 20000+ lines
Okay, that's your problem right there. That's what you need to fix. Splitting things up into two implementation files is a distraction. This is your main problem. There's virtually no circumstances where this is not a terrible way of doing things.
Methods should be a few dozen lines long at most. If you find yourself writing a method that is longer than that, you need to break the functionality down into smaller pieces. Create smaller methods to do part of the job, then call those methods from your original method.
Classes should not be this size. If you are creating a file with more than a couple of thousand lines of code in, it's a huge warning sign that one class is responsible for too much functionality. You should break the functionality down into several classes, each of which is responsible for one key piece of functionality.
I get a link error
If you post a sentence like this to Stack Overflow, it should be accompanied by the actual error you get.
You can make the excessively long method a category of the class:
MyClass.h:
#interface MyClass
#property ...
-(void) method;
...
#end
#interface MyClass (BigMethod)
-(void) bigMethod;
#end
MyClass.m:
#implementation MyClass
-(void) method
{
...
}
...
#end
BigMethod.m
#implementation MyClass (BigMethod)
-(void) bigMethod
{
...
}
#end
However, a 20k line method is absurd. You should really refactor it.
You have several approaches:
you could split your methods into 2 different categories:
//-- MyClass1.m
#implementation MyClass (part1)
#end
//-- MyClass2.m
#implementation MyClass (part2)
#end
I defined 2 categories for symmetry reason; of course you also need a "base" #implementation of your class (i.e., without the category specifier); you can choose whether you define a "base" and and extension category, or "base" and two categories, etc...
or you might try including the second .m file inside of the first one:
//-- MyClass1.m
#implementation MyClass
<first part>
#include "MyClass2.m"
#end
Both should work.
Let alone the possibility of refactoring your class, which would be the best option.

What are the differences between declaring objects in extension and declaring them in primary implementation [duplicate]

What's the difference between putting pseudo-private instance variables in a class extension inside the .m file, or putting them in the newly introduced #implementation brackets like shown below?
Are there consequences, pros, cons over one or the other way? Is internal2 treated differently than internal3 in a way a programmer must care of? (of course there is a difference McKay would say but the question is if you care in practice or not).
// MyClass.m
#interface MyClass () {
id internal2;
}
#end
#implementation MyClass {
id internal3;
}
- (void)internalMethod {
NSLog(#"%# %#", internal2, internal3);
}
#end
source: http://www.mcubedsw.com/blog/index.php/site/comments/new_objective-c_features/
The main difference between the two approaches is that you can include the class extension in a separate header, whereas the #implementation ivars obviously have to go with the #implementation block in the .m file (and there can only be one #implementation for a given class (extensions not included)). The practical result of this is that you can have multiple levels of "private" ivars:
MyClass.h: public ivars
MyClass+Private.h: semi-private ivars
MyClass.m: really private ivars
As a hypothetical example, pretend that MyClass is UIView. In that case, UIView.h is the header that we can all access, UIView+Private.h is the "private" header than only Apple can access, and UIView.m has stuff that only the people specifically responsible for UIView need to know about.
Personally, I prefer to put my ivars in a single class extension in the implementation file, I think it's cleaner that way. I don't think there are any performance advantages or consequences to using one or the other, it's more about being able to code the way you want to.

Is it a good practice to declare properties in implementation file, If yes, what's the use?

Is following code, a good programming practice in objective-C ?
#import "Custom.h"
#interface Custom ()
#property (nonatomic, retain) UILabel *label;
#end
#implementation Custom
#synthesize label;
- (void) dealloc {
[label release];
[super dealloc];
}
#end
The idea behind this is that all properties you declare in your header file, are visible and accesible for everyone outside that class.
To respect the encapsulation principle of OOP, you want to make the scope of certain members of your class as private as possible. So all those members that only your class will use, should be hidden to "the outside world". This can be done by declaring a special type of category called "extension" (it can't have a name, it's declared as #interface Class () ), and the properties inside that extension (along with private method declaration if you want as well)
As to the question whether it's a good practice, that may be discussed among different developers. To me, it is since it's good OOP practice, and also because it helps keeping your header file as clean as possible (and so making it easier for other developers to see what "services" your class provides)
I like to do this to create private interfaces. If a property is only used in your implementation, not in collaboration with other objects, it should not pollute the header (which defines the public interface). You can also hide private protocol implementations this way:
#interface YourClass () <UIAlertViewDelegate>
This way the users of your class don’t have to know that you have an UIAlertView buried somewhere in your implementation.
What could be considered a downside is that your subclasses can no longer access the “private” properties. You have to either move their declaration to the header file (making them public), or create a special “protected” header.
Another option worth mentioning in this context is declaring private variables in the #implementation directive:
#implementation YourClass {
NSString *foo;
NSUInteger bar;
}
These are not statics, they are regular instance variables.
You would want to define label in your header for later use through out other methods in your #implementations. For example, create that label in your viewDidLoad, and you can change it throughout the other methods..

Resources