The Objective-C runtime makes all methods of a class available at all times.
That being said, the whole philosophy of objc since its beginning has been about organizing data and methods into logical, connected framework.
The message-passing way the runtime connects methods to objects relies on all methods being available at runtime.
You can call any method there is a name for on any class at anytime, and the runtime tries to run the "function" (C-function) associated with that class by that name. If there isn't one, you get some kind of warning or runtime exception.
At compile time you only get a warning, traditionally. Modern objc compilers have switches you can turn on to make warnings errors if you want, but generally the runtime traditionally has just flagged a warning, or if there is a fail-over class for unknown methods the message call can get resent to it for handling.
The traditional way of 'hiding' methods was to not list their signature in the header (@interface) file, but to implement them in the ".m" file.
The idea was that internal methods for developers or internal class use would not get called by users of the class if only headers and binary libraries were distributed. Of course if you have the whole source you can look and find them and call them.
Second
"Class extension" in objc can mean several things. First of course is subclassing a class to add features or tune specifications or override methods of the super class. This works as you might expect, with the added facility that you can call the superclass' method if you want to, and indeed that is actually an idiom in objc for initialization of subclass instances.
calls to self = [[super alloc] init]; in sub class init methods are still around.
The next class extension in objc is called categories.
Categories add or override methods in existing classes. Yes, add methods. Yes, override methods. Yes it can be "unsafe". The programmer simply creates a "mini" header and implementation file containing the new methods with the same class name and the category name in parentheses after.
http://rypress.com/tutorials/objective-c/categories
gives good examples.
Lastly is what are actually called "class extensions". Bad name.
They are basically a hybrid of both techniques to achieve "privateness."
You add an extra interface block with an unnamed category "()" to the .m file
and then fill out the method inside the actual class method implementation.
That way it is all defined and implemented inside the main m file and is not
visible when importing the header into other files. C scoping rules apply at compile time and the compiler will choke if it sees a call to the new method
in another file than where it is written. But it is there at runtime as a regular method of the class if you can get a selector for it and call [class performSelector:@sel] on it. But that is what I call meatball surgery, and probably is always a hack, and a "bad idea", and usually leads to a maze of twisty little passages, all different.
There a few older methods of objc that are archaic that restrict what classes in a class heirarchy can perform certain methods such as
subclassResponsibility:_cmd and notImplemented:
but they are not in general use and might act differently on different systems.
The crux of the matter is that objc is sugared-up C. So There are always ways to perform a method if the runtime can find it in its global method list.
performSelector: @sel , objc_message_send(), etc. A programmer that does not have a good knowledge of C should stay out of the runtime's guts, though.
If it's your code and you are writing it for use and not for other programmers to program with, you can call anything you can find, hidden or not.
The protocol system is there to set up rules for calling methods on classes
( err, I mean "sending messages to objects" <cough..>) that makes the compiler warn you if you class doesn't have a method of the name required in the protocol.
Hope that helps a bit.