Must -(void) functions be declared in .h? - objective-c

As the title says, must -(void) functions be declared in .h?
I haven't declared them in my app in .h, yet I can still call them. What are the benefits of declaring them?

You are not required to declare in the header file all methods in the implementation. But if not in the header file than you cannot reference them by literal name in another file, nor can you "forward reference" them in the implementation file.

Related

Swift read private property from a .m file

I have a library that is written in Objective-C and using .m and .h files.
Is it possible for me to write an extension method for that class and get access to a private property that is only defined in the .m file and not defined in the .h file?
I have tried with the .valueForKey but I only get
payload_data_0
payload_data_1
payload_data_2
instance_type
which all are of type Builtin.RawPointer.
No. The only way for you to access it is to define it publicly in the header.
No, technically you can't. The documentation is very clear about this:
Extensions can add new computed properties, but they cannot add stored properties, or add property observers to existing properties.
If you need this for testing purpose, consider moving the private property declaration to a separate header file, like MyClass+Test.h , and have it added to the bridging header. But guess what, this makes those properties public anyways. Not a recommended solution.

Apple mach-0 linker error NSInteger

I am getting the following error(and YES, I have already search through google again and again):
I have multiple 'extern NSInteger' defined and can use them, though this 'timeofclick' for some reason causes this error
On other threads people talk about adding frameworks and including stuff, but here I'm just using one more NSInteger
In my .h
In my .m
Could it be that you haven't actually defined the timeOfClick variable anywhere (inside a .m file). Putting the extern declaration in a header says "don't worry, this thing will get defined somewhere, and you'll find it at link time". If the linker comes along (like here) and it can't actually find the variable defined, you'll get an error like this.
Essentially you want to have an NSInteger timeOfClick somewhere in an implementation (.m) file.
I think you got the error because you didn't write
#synthesize timeofclick2;
under your #implementation ReactingViewController.
By default, the compiler will generate an instance variable (ivar) for you if you only declare a property but you don't synthesize it explicitly. The generated ivar usually goes by _<property_name>, like in your case _timeofclick2, instead of the same name as the property.
Thus, you got the error when you tried to call timeofclick2 without _ prefix because there is no ivar with that name.
By explicitly write #synthesize <property_name> (without '<..>'), the compiler will generate ivar for you with the exact name of the property.
So, if you add the code I mentioned above, the compiler will create ivar timeofclick2 for you. Then you can access it via your extern.
...Or another solution, you can just change the extern from
extern NSInteger timeofclick2;
to
extern NSInteger _timeofclick2;
Then you'd be fine :D

How do I know when do put my properties and methods in the .h file and when to put them in the .m interface?

How do I know when do put my properties and messages in the .h file and when to put them in the .m interface?
I am thinking messages which are public like init should be in the .h file. What about properties which describe the class e.g. configuration type etc.
When you want to restrict access of any property, you can define that in .m file using class extension etc.
There is no as such rule defined for putting properties in .h or .m file, you need to check which properties you want to access outside the class(define those in .h) and which you do want to access outside(define in .m).
According to the Apple docs, one declares properties in "#interface" (.h) files. If you want to have private object only variables, those are called ivars and you wouldn't synthesize accessors to them.
Private properties (or "property redeclaration" in the docs) can be used in things like class extensions or protocols.

Global variables in Objective-C - difference in extern and top of .m file declaration

I know you can define a global variable in Objective-C by using "extern", but I just realized that the variables I had declared at the top of my .m file before my first method were also accidentally global (and that was causing some problems). I moved them into the #interface part of my header file, which I think correctly declares them as only existing within the class, which has solved some of my problems, but I am still a bit confused.
What is the difference in declaring a variable as extern and putting it at the top of a .m file? Or do those result in the same thing?
extern is a way of explicitly stating, for readability and compile-time enforcement, that you are just declaring this variable here, and actually expect it to be defined elsewhere. If you were to also try to define the extern variable the compiler will tell you the error of your ways. This is useful for global variables to prevent name collision and multiple definitions, both of which will get you linker errors. The extern keyword itself, however, does not make the variable global.
What does make the variable global is the position of its declaration in the file. If you were to declare a variable outside the #interface in a class' header file, you would have declared a variable that is shared across and visible to all instances of your class, as well as anyone who #imports the header. If you were to (and apparently did) declare a variable outside of the #implementation in your class' .m file, you would have also have declared a variable that is shared between all instances of your class, but is not visible to anyone who #imports you header.
So, use the position of variable declarations to determine scope. You will only define these global variables in one place. For all other places that you declare them, prefix the declaration with extern to make the code readable, your intentions clear, and to make sure you don't also try and define it again.

Objective-C : Object declaration question

there is something I try to understand. I have this object declaration in my AppsController-Class for a Cocoa Application
NSMutableArray *personArray;
In can put this declaration inside the Header file or inside the implementation of the class in the code file. It makes no difference. I can even put it outside the #implementation context right under the #import commands.The Application works just fine.
Since I don't inherit from the AppsController Class or do anything else fancy with it I wonder what might be the difference between these types of declarations?
Where does the declaration really belong?
It depends on how you want to use the variable. If you place the variable declaration inside the interface for your class, each instance of your class will have its own copy of the variable, which is kept separate from all other instances of your class:
#interface AppsController : NSObject
{
NSMutableArray *personArray;
}
Each instance of the AppsController class will have its own copy of the personArray variable, which is separate from all other instances of the class.
If, however, you define the variable outside of the interface, it becomes a global variable, and it is a shared (instances of your class do not get their own copy), and can be accessed from any instance of your class. If you declare it in the header as such:
NSMutableArray *personArray;
it is also visible to methods in other files and classes that include your header.
If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.
Since your object is a controller object, I am guessing that you only have one instance of it present in your application. You should declare the variable either:
As an instance variable if your personArray variable needs to be unique to each instance of your controller class (even if you only have one instance now, you may have more than one instance of it in future).
As a class variable (using the static keyword) if you want the variable to be visible to all instances of your class, with only one, shared instance of the variable.
As a global variable if you want the variable to be a single instance (not unique to instances of your class) and also visible to other classes or code in other files.
You should probably put it in the interface section of the header file, that way there will be one instance of it per object instantiated. Which I presume is your intention.
I think if you put it elsewhere it will be treated as a global variable. Ie, there will only ever be one instance of personArray, and it will be visible from anywhere in your application.
Your application is probably working fine, because you only have one instance of your AppsController Class, and no other variables called personArray. If you ever need a second AppsController, or another variable elsewhere called personArray, you'll run into problems.
If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.
just to clarify, the reason variables declared inside the implementation file but outside the implementation section are not available outside the class, is because other classes are not aware of anything inside the implementation file. your import statements refer to headers, not their implementations, so they know nothing of those implementation file declarations.
anyway, to create a static variable accessible only by a class, use keyword static when making a declaration in an implementation file. you can put it at the top of the file, at the top of the implementation section, or inside a function, depending on what you want the scope to be.
edited: corrected, thanks peter