Why do I need a class extension to make a method private? - objective-c

I've been reading a little bit about this and what I don't understand is why people adds class extensions to make a method private.
Wouldn't it suffice to just leave it out from the header file?
It looks to me to be enough, but I might be missing a bigger point?

Short answer: now (as of Xcode 4.4, I think), you don't. Reason: you don't need to forward declare methods. Put your private methods in your .m file, and you're done.
Previously (Xcode 4.3 and older), you had to forward declare your methods before you could call them. Because you already declared the class in the .h file, you can't declare it again in the .m file, so a class extension is the way to add methods to an already declared class.
Edit: as #Yar mentioned above (and below), a private method in a .m file that isn't declared would not be visible to subclasses of that class, meaning it would be impossible for that subclass to call or override that method. Still, I'd be inclined to just not bother declaring it, unless/until you end up with a subclass that needs to override or call it. For me this happens pretty infrequently.

It would be sufficient to leave it out of the header file, but then your subclasses don't know it's there, either. This means that you get a compiler error if you try to call these private methods. This is why you use an external file that is a class extension, and all subclasses import that extension in the .m file.
Obviously, this situation is not ideal because you get three files for each class, minimum, but the joy of Objective-C is about making LOTS of files and not worry about it. If you are scared to make files, you will end up with big classes, which is an anti-pattern.
One problem is naming the class extension file, since it's a category with no, um, category. I've been using a scheme like Blah4Subclasses, which is probably about as bad a suggestion as you'll get.

the class continuation has nothing to do with access, wrt the translation. the objc language does not specify access for methods. so it's a relatively weak private. what people end up falling back on is the ability to hide method declarations in their implementation file.
the important point to take away is that the class continuation is generally only visible to your class (because it is often placed in the *.m file). this pattern reduces the likelihood of a private method's use because it is not visible to the client, or to the compiler (in translations other than the one which contains the class' #implementation in the typical structure).
also note that the class continuation is capable of a lot -- so it's a convenient place to store your private #interface; properties, ivars, methods.
lastly, it is also a habit from earlier days, because it was a more frequent necessity. not too long ago, the declaration was added so the compiler knew the object responded to a specific selector, and the signature of that selector. because clang parses the entire #implementation block these days, many people find they do not need the declarations in the class continuation because the compiler can match methods seen in the #implementation, regardless of order of declaration.

You can add #private in your .h file.

Related

In objective-c what is the difference between creating a class in the same .h file by writing, and creating a new file as Objective-c class?

I am a beginner in Objective-C. I was trying out basic Objective-C programs in Xcode5. I created a project, say Example1 in which I wrote a program with two classes, say Class1 and Class2 in the same .h file. I created the class - Class1 by - File-->New File--> Objective-C Class (NSObject). That created this,
#interface Class1 : NSObject
{
}
#end
The second class Class2 I created just by adding,
#interface Class2 : NSObject
{
}
#end
Now, when I create another class by creating a new file (Like how i did Class1), I get another set of .h and .m files.
My doubt is, what is the difference between using different classes in the same .h file and different .h files ?
In ObjC is is traditional to give each class its own .h and .m, and to give these files the same name as the class. In most cases, this simplifies finding your way around the code. It is not required. You could of course put all you class definitions in a single .h; you could put your entire program in a single .m with no user headers at all. But it is traditional and is generally a good practice to split them up.
There are exceptions. Sometimes two classes are extremely related and are put together into a single header. A famous example is NSArray and NSMutableArray, which are both defined in NSArray.h. Apple pushes this further with NSCalendar.h which which includes NSDateComponents. (Personally, I probably would have split NSDateComponents into its own header, but this is an example of differing opinions.)
In very large systems (like Cocoa), the number of header files can be a concern for compile-time efficiency, so there are certain pressures to merge header files that are extremely likely to be used together. It is rare for this to matter that much in moderate-sized projects. (And it doesn't actually matter that much in Cocoa either, since Cocoa headers are almost always brought in through pch, and now through modules.)
As a beginning programmer, I would err on the side of consistency. Just put each class into its own header, with a matching .m. As you explore more existing frameworks, you will gain better intuition about when merging classes into a single header might be appropriate. I almost never do it myself.
There is one other kind of merging that you may come across. It is legal to declare an interface inside of a .m file. This is useful for creating private helper classes. I've done that occasionally, but I almost always find myself regretting it and splitting the private class into its own files. It just gets too annoying to find the code when it's not in a consistent location. But, sometimes for tiny, private data classes, there is sometimes justification for defining them directly in the .m.
normally each class has its own files .h and .m but nothing is stopping you from writing all classes in a single file if that is ok for you.
If you declare two or more interfaces in the same file. the methods and properties of all interfaces except the main interface couldn't be reach from the outside world, Because you could implement only the main interface in .m file.

Protected variables with modern objective-C?

I feel that modern Objective-C encourages using instance variables as properties for memory management and key-value observation. That works fine, and I'm using interface inside implementation file for private variables, like this:
#interface MyClass ()
#property NSObject* myVar;
#end
However, how can I make protected variables? In case above, my subclasses won't be able to see properties declared like that. I can go iVar route, but then it feels off with the rest of the code if private variables are declared like above and protected are iVars.
I've read this solution: Workaround to accomplish protected properties in Objective-C, but it seems to overcomplicate code too much.
Your best option is to use a category in a second header file, e.g. MyClass_protected.h, and include it in the main class and subclasses, as suggested in the solution you link. It's really quite straightforward, not "overcomplicated" at all, just one additional file.
Objective-C has very strong introspection characteristics. No matter how or where you declare a property (or any other function, for that matter), you can access it from anywhere. You will get a compiler warning unless the code you're writing can see the corresponding declaration or implementation (unless you use an introspective method like one of the performSelector... family). The only reasons for the interface are name-safety, type-safety, and preventing compiler warnings. Therefore, you have a few options:
The main class interface
You get implementation safety (i.e. the compiler will give a warning if you don't implement a method). However, every class (that imports yours) will see the methods. You can use a comment to indicate that the method should be protected, but of course no one will see it unless they check the source. I most often use this when I'm the only programmer on a project, as I know what should be protected and what shouldn't.
A category in the same .h file
As above, programmers won't see it's protected unless they check the source, but if they do it will be much more obvious. If you declare this in a named category (#interface MyClass (protected)) you lose type safety, but it's even more clear what you intend. I most often use this to emulate abstract methods - i.e. explicitly not implementation-safe, but should be visible to everyone.
A category in the subclass's .m file directly
It's a bad idea, don't do it. You do only see the methods in the subclass, but you lose implementation safety and it really just feels wrong. I have only ever used this for unit tests, and I eventually migrated those to a separate header.
A category in a separate header (MyClass_protected.h)
The preferred solution, and the closest Objective-C can get to protected methods. It's just one more file, seriously, don't get your panties in a bunch over that. You can use the class extension (they are anonymous categories) and you won't lose implementation safety. It's only visible to classes that include it, which should only be subclasses; the fact that the contained methods are intended to be used as protected should be obvious to all but the most incompetent programmers because of the header name.

How to automatically verify all methods are declared in xcode

I am working with Objective-C in Xcode. I was wondering is there any mechanism to proof your code to make sure all functions and methods are declared in the .h file or in the private #interface method?
To clarify I will be on a coding tangent and will write a method directly in my viewController.m file
- (Awesome*) generateAwesomeOfMagnitude:(NSFloat)magnitude { ...
and I will forget to add the heading to the viewController.h file. If this is a private method nothing notifies me that I've done this so I have to go back through and verify that everything was declared manually when Im done. Is there any way to check automatically?
Note: Im looking to make the complier to throw a warning. Is there a setting is really what I should have asked.
Omar's answer is correct - asking an object if it will respond to a selector is the preferred method for probing objects to see if they'll respond to a method at runtime. However, the question asks "How to automatically verify all methods are declared?" (presumably at compile time). And the answer is, short of writing something yourself, you cannot automatically do this.
This is part of what makes Objective-C 'dynamic'. You don't have to declare a method anywhere. This makes things possible like:
id anUnknownObject = [[NSClassFromString(whoKnowsWhatIllBe) alloc] init];
[anUnknownObject performSelector:#selector(whoKnowsWhatIllDo)];
This means, for example, you could fetch a string from a web service and instantiate a class based on the string alone (of course the class must be around at run time in order to be instantiated, but the compiler doesn't have a clue).
This doesn't mean you should program this way, but it means its possible, and, as with most things, there are appropriate use cases, and it's a great distinction of the language. It promotes extreme decoupling, polymorphism, and tons-o'-fun patterns.
It's generally regarded as best practice to declare private methods in .m class extensions, but the value of this is for the programmer, not the compiler. Some (to include a major contributor to Objective-C who shall go nameless in public forums for the time being) have also suggested that there isn't a need to type the names of all your methods twice in a single file (less code, less mistakes -a bit more scrolling if you're looking at someone else's class for the first time). Having a nice-n-tidy public API is exactly what the header is for. Having a clean implementation is important, but the assumption is that once you're in the m, you're in private territory anyway. Scroll around. See what the method names are.
To check if method exists at run time in the class use
if([yourObject respondsToSelector:#selector(generateAwesomeOfMagnitude:)])
//has this method
else
//does not have this method
but you dont get any warning if you define a method in the .m and dont include it in the .h file
However if another class is accessing a method that is not declared in the .h file you will receive a warning

Does the order of methods in my .m file matter to the compiler?

I think that i have noticed moving certain methods around causes errors when i compile that are remedied by putting the method back where it was.
am i making this up? is there are rhyme or reason to the order that these need to be in? is decided by the order of my .h? what about delegate methods and inherited methods?
Yes, but only if you reference a method in an earlier place without declaring it elsewhere. You may want to declare your method in your main #implementation or stick it into a class extension in your implementation (.m) file.

methods in objective-c

How come sometimes you need to put the method signature in the .h file and sometimes you don't?
Methods which you are overriding from your superclass do not need to be redeclared in your class's interface. It is sometimes a good idea to do so, but is not required.
Similarly, you do not need to declare methods that you are implementing from a protocol; simply declaring that you conform to the protocol is enough.
You should declare methods which are "new" to your class: those which are not inherited from a superclass nor part of a protocol. This is to give the compiler the necessary information to determine the correct argument and return types and is necessary to the correct running of your application.
Those answerers who have said that you don't have to declare your methods are technical correct, however be aware that this is a very bad practice as the compiler will infer parameter and return types which may not match the definition and can cause undefined behavior when the method is called.
This is just because some people like to put it in the header. Some people don't. You might have notice that in the .h files there is an #interface. You technically just need to put method signatures there. But, trust me, it makes life a lot easier if its in the header file (mostly because its more readable).
Because technically objects have no methods in Objective-C as we know them from other languages, instead what you are doing is to send messages to the object, if there is a corresponding method (message) on the object with the same signature, it will be called. This means there is no real need to have the signatures in the header however it is good practice to have them so that the compiler can warn if you write the wrong signature.
It's always a good idea to declare methods in the #interface before using them (it helps the compiler, allowing the compiler to help you by catching more type errors), but the header file should really only have public methods (methods you want other classes to know about). For private methods that are used internally by the class, a class extension within the .m file is a good idea, i.e.:
#interface MyClass ()
-(void) superSecretMethod;
#end
It's always a good idea to put the signature of your public methods in the .h file. You will avoid compiler warnings, and you'll know that if you do get a warning, it's for a good reason (you mistyped your method name, parameter type, etc).