Is interface to an implementation is just like a function declaration (in a header file) to a function definition?
What if I didn't list in the interface all methods that are already implemented? What about instance variables as well?
Yes interface and implementation could be considered analogous to header and definition.
If you don't list some of the implemented methods, you won't be able to used them from other classes. Also if they are not defined in the #interface section, the compiler will complain if you try to use a function that has been implemented after the call
#implementation
- (void) functionA
{
[self functionB]; // error, because 'so far' functionB has not been defined
}
- (void) functionB
{
}
EDIT: See Martin's comment below. END EDIT
If you don't define instance variables, and you use them you'll get errors. Any variable that you use MUST be defined, either locally or in the class.
Answers to your questions:
Is interface to an implementation is just like a function declaration (in a header file) to a function definition?
YES
What if I didn't list in the interface all methods that are already implemented? What about instance variables as well?
These methods will be taken as private methods and variables which will be accessible in that particular class.
variables declared in your interface, as in 1., are visible in other classes that instantiate objects of MyClass. The variable declared in 2. will only be visible inside of MyClass. Here is something you should read: http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/
http://iosmadesimple.blogspot.in/2012/11/interface-and-implementation.html
I guess all these will help you in understanding these things in deeper.
Related
I just started picking up objective c and I have been following a tutorial online.
In the tutorial, it set the NSMutableAray pointer in the implementation (.m file) in the curly brackets.
I thought the pointer variable should be declared in the header file.
What is the reason / benefit of having the pointer variable in the implementation file in the curly brackets?
#interface AppDelegate ()
#end
#implementation AppDelegate
{
NSMutableArray *_players;
}
Two reasons for declaring instance variables in the #implementation:
The instance variable is private to the implementation, it is implicitly private, cannot be made public, and no even subclasses can see it. This restricts access from outside the implementation to the value of the instance variable, or to setting its value, to public (or protected) methods/properties declared in the interface.
It de-clutters the public #interface by removing details which are not relevant to the user of the class, but only to its implementation.
Originally Objective-C did not support declaring instance variable in the #implementation, but it has for a few versions of Xcode/clang by now. In old code you will still see instance variables in the #interface, but it is better in new code to declared them in the #implementation.
HTH
Apparently so private interface is unavailable outside
Is it possible to initialize a property in a category?
For example, if I have a mutable array property called nameList in a class. Is it possible to have a category created for this class to add an object to the array property before any of the category method is called?
If I understand you correctly, and others are interpreting your question differently, what you have is:
A class with a property
A category on that class
And you want to call a particular method automatically before any category method is called on a given instance, that method would "initialise" the category methods by modifying the property.
In other words you want the equivalent of a subclass with its init method, but using a category.
If my understanding is correct then the answer is no, there is no such thing as a category initializer. So redesign your model not to require it, which may be to just use a subclass - as that provides the behaviour you are after.
The long answer is you could have all the category methods perform a check, say by examining the property you intend to change to see if you have. If examining the property won't determine if an object has been "category initialized" then you might use an associated object (look in Apple's runtime documentation), or some other method, to record that fact.
HTH
Addendum: An even longer/more complex solution...
GCC & Clang both support a function (not method) attribute constructor which marks a function to be called at load time, the function takes no parameters and returns nothing. So for example, assume you have a class Something and a category More, then in the category implementation file, typically called Something+More.m, you can write:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(The static stops the symbol initializeSomethingMore being globally visible, you neither want to pollute the global name space or have accidental calls to this function - so you hide it.)
This function will be called automatically, much like a the standard class + (void) initialize method. What you can then do using the Objective-C runtime functions is replace the designated initializer instance methods of the class Something with your own implementations. These should first call the original implementation and then an initialize your category before returning the object. In outline you define a method like:
- (id) categoryVersionOfInit
{
self = [self categoryVersionOfInit]; // NOT a mistake, see text!
if (self)
{
// init category
}
return self;
}
and then in initializeSomethingMore switch the implementations of init and categoryVersionOfInit - so any call of init on an instance of Something actually calls categoryVersionOfInit. Now you see the reason for the apparently self-recursive call in categoryVersionOfInit - by the time it is called the implementations have been switched so the call invokes the original implementation of init... (If you're crosseyed at this point just draw a picture!)
Using this technique you can "inject" category initialization code into a class. Note that the exact point at which your initializeSomethingMore function is called is not defined, so for example you cannot assume it will be called before or after any methods your target class uses for initialization (+ initialize, + load or its own constructor functions).
Sure, it possible through objc/runtime and objc_getAssociatedObject/objc_setAssociatedObject
check this answer
No it's not possible in objective c.Category is the way to add only method to an existing class you can not add properties in to this.
Read this
Why can't I #synthesize accessors in a category?
I've been learning Object Oriented Programming in Objective-C and I'm a little confused about method declaration and implementation.
In some lectures I've been studying, the professor declares public methods in the .h file and then implements them in the .m file; or he may declare them private in the .m file and them implement them in the #implementation ClassViewController section.
Sometimes, however, he doesn't declare methods at all and just skips to method implementation in the #implementation ClassViewController section.
How do I make this distinction where to declare something either public or private, or not having to declare anything at all?
Methods should be declared publicly when you want that method to be accessible to outside classes, and privately otherwise. A method that was declared in a superclass does not need to be declared again in it's subclasses if you override it. As far as methods that are implemented without any previous declaration, that method can still be called, but it is only 'visible' to methods below it in the file, and will throw a warning otherwise. As such, this is rarely done (it is declared privately instead), with the exception of if that method is intended to be the target of an #selector.
The short answer is that all methods should be declared (either publicly or privately).
But I suspect what you actually saw your professor do was override a method that was already declared in a superclass.
So for example, if you wanted to override viewDidLoad in your CustomViewController, you would not declare viewDidLoad again, because that method was already declared in the header for UIViewController (the superclass).
You would simply go to the implementation of your subclass and write your implementation of viewDidLoad which would override the one you inherited. If you go watch the lecture again, I'm guessing that is what you saw.
I'm using a Objective-C framework for game development called Cocos2d-iphone.
This is how I create a button-graphic in the game:
CCMenuItemImage *battle;
battle = [CCMenuItemImage itemFromNormalImage:#"BattleFightOption1.png" selectedImage:#"BattleFightOption2.png"
target:self selector:#selector(battleFightOption)];
Basically, when the user clicks the button, method battleFightOption runs.
But I wonder, I never did define battleFightOption in the interface.. so, my question is: when is it necessary to define a method in the interface, and when is it not?
In short, every method that is meant to be used from outside the class must be declared in the interface; methods that are internal to the class implementation are omitted. The latter are typically declared in a class extension.
When you use a selector like #selector(methodName:), methodName: is called dynamically at runtime. The compiler doesn't have to know where it is, and doesn't check that the method exists when you compile.
However, it is still a good idea to declare it privately, which is generally done by putting an unnamed category at the top of the .m file (generally referred to as a class extension):
#import "Class.h"
#interface Class ()
- (void)privateMethod;
#end
#implementation Class
...
Anything that you intend to be public, called outside of the class, should be defined in the interface. If you are going to only use #selector(battleFightOption) you really do not need to define the method anywhere but I would recommend that you add a definition in the class extension just as you would any other private method.
Why are people using
#interface ViewController : UIViewController
{
#private
UIButton* button_;
}
#private declarations in public headers? Declaring a variable inside an implementation yields the same result, doesn't it? It feels strange to me, I thought a public header should only contain really public members. What to do with protected members?
#implementation ViewController
UIButton* button_;
#end
The only difference I know of is that this variable is only visible inside the current compilation unit (the .m file, right?)
Does the same hold true for methods? I could compile fine with proper method ordering or forward declarations. Why do people care to declare categories for private methods? For testing purposes only?
The variable declaration inside the #implementation block will create a global variable, and not an instance variable. Instance variables need to be defined as part of the #interface.
While you can create an additional #interface block, by means of a category or extension, but it can only contain method declarations, and not instance variables.
I would say that while it might "feel" wrong to you to put private instance variables in a supposedly public header, I wouldn't worry about it.
Take a look at pretty much any header file for a Cocoa class (except for the cluster classes), and you'll see that Apple declares their instance variables in their public header files.
Since Apple is OK with it, I don't think you have much to worry about. =)
FYI: All instance variables are protected by default.
Does the same hold true for methods?
No, methods are visible to any part of the program. If you know the selector you can callit.
I could compile fine with proper method ordering or forward declarations. Why do people care to declare categories for private methods? For testing purposes only?
Private categories are a form of forward declaration. You can think of them as if they were C prototypes.
Andrew
#private is referring only to the iVars.
By default you can access ivars of an instance like so:- id iShouldNotDoThis = foo->bar;
#private means you can't access the ivar like that and have to use the access methods.
id thisIsBetter = [foo bar];
Nothing to do with private categories or methods.