Variables inside protocols in Objective-C - objective-c

Why is there a provision to include a variable inside a protocol declaration, when is this ever used.
#protocol SampProtocol
int i;
- (void)func;
#end

There isn't any such provision. clang issues an error if you try to compile that code; gcc considers the int i; statement as part of the parent scope (which is probably a bug).

Related

type name does not allow storage class to be specified

#interface Foo : NSObject
{
extern int gGlobalVar;
int i;
}
-(void)setgGlobalVar:(int)val;
#end
#implementation Foo
-(void)setgGlobalVar:(int)val
{
i = 5;
NSLog(#"i = %i", i);
gGlobalVar = val;
}
#end
I can declare i in interface and use it in implementation without any errors. But I cannot declare a variable of the type extern in interface. Why is this so? Why do I get an error which says that: "Type name does not allow storage class to be specified"?
Short Description:
The bracketed section of a class's #interface OR #implementation is only for declaring instance variables (aka "ivar"). The extern keyword is only for use with global variable declarations (or functions, but that's another topic.)
Therefore, you cannot declare an extern ivar.
Gritty Details:
Variables are first declared, and then defined. This distinction is typically blurred for variables in local scopes, as a locally declared variable without an explicit definition will often be allocated and given a default value by the compiler.
Global variables are potentially available in any scope, provided that scope knows the global exists. That's where the keyword extern comes in -- it declares that the global variable exists, and was defined elsewhere. This is only useful when you want to access a global variable in different code files.
Best Practices: Your book has some code that declares an extern variable in an implementation file (e.g. ".m" files, etc.)... that can work, but it's a bad practice because you're making potentially bad assumptions about whether that global actually has a valid definition elsewhere. (But, fancy compilers will discover this type of error.)
Instead, the best practice is to declare an extern variable once in a header file, have an accompanying implementation file that's dedicated to defining the externs in that header, and then include that header in other implementation files that want to use that global variable.

Access to global vars

In Xcode / Objective C: Is there a syntax that you can force access to a global variable. I notice that a class variable silently hides any global variable. See example. Not suggesting it's a good idea but just curious.
int someVariable = 56;
#implementation Example {
int someVariable;
}
- (void)print {
printf("Var=%i\n", someVariable);
}
The convention used by Apple and most Objective-C developers is to capitalize global names, and if the project uses a prefix, to prefix them as well. So for example:
int SomeVariable = 56;
or
int XYZSomeVariable = 56;
That way your global names can never collide with names of instance variables (not class variables, by the way -- there is no such thing in Objective-C), local variables, or arguments so long as you observe the other half of the convention: local names always begin with a lowercase letter.
Edit
I should also mention that there's a longstanding convention in Objective-C to prefix instance variable names with an underscore, which would also help avoid the problem. In fact, the LLVM 4.0 auto synthesis feature now automatically synthesizes ivars with an underscore prefix for declared properties unless you tell it not to. So for example, if you had declared the instance variable in your example as follows:
#implementation Example
{
int _someVariable;
}
...the ivar couldn't have shadowed the global variable.

objective-c - global variables

How do I declare a variable in the main.m file so that it is available in all the classes?
If I simply declare it in the main function, the compiler says it's undeclared in the class method.
Must I declare it in an object like this?
#public
type variable;
All you need is to use plain old C global variables.
First, define a variable in your main.m, before your main function:
#import <...>
// Your global variable definition.
type variable;
int main() {
...
Second, you need to let other source files know about it. You need to declare it in some .h file and import that file in all .m files you need your variable in:
// .h file
// Declaration of your variable.
extern type variable;
Note that you cannot assign a value to variable in declaration block, otherwise it becomes a definition of that variable, and you end with linker error complaining on multiple definitions of the same name.
To make things clear: each variable can be declared multiple times (Declaration says that this variable exists somewhere), but defined only once (definition actually creates memory for that variable).
But beware, global variables are a bad coding practice, because their value may be unexpectedly changed in any of files, so you may encounter hard to debug errors. You can avoid global variables using Singleton pattern, for example.
Not really sure why you want to do it, but you could if you wanted.
main.m:
int someGlobal = 0; ///< Added outside any function, at the top say.
SomeClass.m:
extern int someGlobal; ///< Added at the top, outside the class implementation.
...
- (void)useGlobal {
NSLog(#"someGlobal = %i", someGlobal);
someGlobal = 5;
NSLog(#"someGlobal = %i", someGlobal);
}
But please, think carefully before embarking on using something like this!
Besides debugging, I see no reason to even try and modify the main.m file to directly interact with your application logic.
You can try to define a constant on Your_project_name_Prefix.pch file, if that suits your needs. Or declare a static variable on your application delegate, or any of the classes of your app.
To learn more about constants and static variables, follow this link:
http://iosdevelopertips.com/objective-c/java-developers-guide-to-static-variables-in-objective-c.html

Objective c - int and char[] declared in .h, life cycle?

I've struggling with the memory of my app (alloc, retain, release, etc...) for a while, but there's something I dont finish to understand.
If I declare this in my .h file:
int ex1;
char ex2[10];
What is the life cycle of these variables? Imagine that I want to use these variables in different parts of my .m code, in methodA I'm going to assign a value, and in methodB I'm going to read them.
Can I be 100% sure that the variables are not going to be released in any moment of my .m?
Thanks
As they are primitives, yes. They will not be retained or released. If you want to declare them as properties, you should declare them as:
#property (assign) int ex1;
and
#property (assign) char ex2[10];
Then in your .m file #synthesise them as normal and you will be able to use [myObject ex1] and [myObject ex2]
The idea is really quite simple in Objective C -
if you ever call alloc on an object then you are responsible for calling release on it.
If you ever call retain on an object then you are responsible for calling release on it.
If you want to make sure that noting else is going to release it from under you, and you didn't alloc, then call retain on it.
Obviously, however these rules apply to pointers to objects, not primitives like int or char.
You shouldn't be declaring variables in a .h file as this can lead to linker errors.
rather you should extern-declare them in the .h file and declare them properly in a .c/.m file. For example:
// In the .h
extern int ex1;
extern char ex2 [10];
// In the .c/.m
int ex1;
char ex2;
The reason being is that multiple .c files can include your header and you will have multiple definitions of the same variables.
Also, bare in mind that Objective-C is a strict superset of C. This means that anything that works in C works the same way in Objective-C. You only need to worry about retain/release/autorelease for Objective-C objects, basically anything that uses this syntax:
#interface MyObject : NSObject
{
// My vars
}
#end

What class of Objective-C variable is this?

I am working my way through some Objective-C code that I did not write and have found a variable declaration style that I am unfamiliar with. Can anyone tell me the scope of the variable 'myVar' in the class implementation below? Note that this appears in the '.m' file and not the interface declaration.
#implementation MyClass
#synthesize ivar1, ivar2;
NSString* myVar; // <- What is the intent?
- (id)init {
...
#end
To me the intention appears to be similar to that of a member variable. What are the advantages of declaring a variable in this way instead of using an ivar in the #interface declaration?
It's just a plain old global variable. There's only one instance of it, and it can be accessed by any code within the same file translation unit (the final file you get after running the preprocessor). Other translation units (that is, other .m files) can also access that global variable, but in order to do so, they need to use an extern statement:
extern NSString *myVar;
extern says "this is the name of a global variable, but it's defined in a different translation unit". The linker resolves all of the extern declarations at link time.
a poorly named global variable...
I'm not too experienced in ObjC but I'd say that is a global.