Declaring or not declaring in Objective c - objective-c

I'm starting with obj-c and there's a few things I don't get.
First of is I (oh I'm coming from an AS3 coding perspective) thought that if you wanted to have a variable in your class, you needed to declare it first in the header with the #property operator, and then #synthesize in the .m file, and also you had to declare the method in the header as well, but I've come across situations where variables are just defined in the methods in the .m file, without any declaring anywhere, and the same for the methods, methods that are just written straight into the .m file with no declaring and they work fine.
So what's the point of the #property/#synthesize for variables and declaring the methods in the header files? it is all to do with scope?

What you are talking about is not referred to the declaration of a variable but to expose it from outside of the class through a getter and a setter.
The #property/#synthesize are just a shortcut to automatically create two methods which are
- (void) [class setVariable:(type)var]
- (type) [class variable]
that can set and get the variable from other classes.
Not every variable needs to be set or got from outside the class.

The header (.h) file should contain what you want other classes to know about this class. A class extension -- an interface section inside the .m file -- is a good place for private declarations. (If a method is defined before it is used, that serves as a declaration. It isn't optimal but it works.)

There are three main categories of variables in Objective-C:
Instance variables
Static-scope variables (static, global, and function-static)
Automatic-scope variables (locals and function/method parameters)
When you declare and synthesize a property, an instance variable is created for you. Local variables, on the other hand, are declared in the scope of a code block, and cannot be declared through a property.

Related

What does this kind of header mean in a .h file?

I recently came across this formatting for a .h header file. Can someone explain to me why this is done this way and what it means? In particular, I am confused about what is in the first set of braces/the repetition? How does this differ from if I were to delete the braces and everything between them?
#interface ACustomView : UIView
{
float chartWidth, chartHeight;
}
#property (nonatomic, readwrite) float chartWidth, chartHeight;
#end
How does this differ from if I were to delete the braces and everything between them?
A #property, of itself, is just a method declaration (or, in your case, two method declarations, a getter and a setter). Typically, you want those methods to be backed by actual instance variable which the getter and setter will get and set. That is what is declared in the curly braces.
Deleting the instance variable declarations in your code doesn't change very much, however, because the compiler will use your #property declaration to autosynthesize instance variables for you. In other words, you typically need instance variables backing a #property, but you don't need to declare them explicitly.
In your particular code, however, you have not shown enough information to reveal what's really going on. A lot depends on what you do (or don't do) in the corresponding .m file. If you say #synthesize for this #property, what is synthesized will be these instance variables, chartWidth and chartHeight. But if you don't say #synthesize, you'll get autosynthesis of instance variables _chartWidth and _chartHeight, and so now, if you also declare chartWidth and chartHeight instance variables explicitly, you'll have something of a mess on your hands.

Variable in implementation file

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

Guidelines for declaring methods in #interface, in an extension, or not declaring at all

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.

Where should I initialize variables in objective c?

In objective c, should I overwrite the init method to initialize my variables? If the variables are properties can I still access them the usual way to set their initial value?
In objective c, should I overwrite the init method to initialize my variables?
Yes. Specifically, the designated initializer(s).
Your subclass may also specify another construction stage (e.g. viewDidLoad). Also, the object's memory is zeroed when it is allocated, so you do not need to set them explicitly to 0/nil (unless you find it more readable).
If the variables are properties can I still access them the usual way to set their initial value?
You should avoid using the object's instance methods/accessors, and access ivars directly in partially constructed states (notably the initializer and dealloc). There are a number of side effects you will want to avoid - Example Here;
you can initialize you variables in viewDidLoad method of a view controller.
Variables declared in the classes interface will automatically be initialized to there default value, 0 for integral values and nil/NULL for classes and pointers. If you need to initialize the variables to other values then you need to override a guaranteed entry point for you class. A custom class inheriting from NSObject for example you will simply override init. If you are working with a view controller loaded from a NIB file then you could override initWithCoder: or – awakeFromNib. You should always check the documentation for whichever class you are inheriting from and find the designated initializer for that class. Sometimes you will need to set a common initializing method and call it from various initializers. Also if you have a variable that is also a property it is recommended that you should set the property and not the variable directly.
should I overwrite the init method to initialize my variables?
Instance variables: yes, although they are by default initialised to 0/nil/false already.
If the variables are properties can I still access them the usual way to set their initial value?
Yes you can. Apple advises against it because of the danger that a subclass has overridden the set accessor to do something unexpected. In practice, this is rarely a problem.

Objective-C: what is private what is not?

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.