I do not have a background on C/C++. I just started learning Objective-C after a past using other languages.
In which situations should I use static declaration of a variable over regular ivars or properties? What do I gain doing this?
thanks
Global variables and functions
By default, all symbols (global variables and functions) are exported (made visible to code in other source files). If a global variable is declared static, it is not exported. That means it is only accessible to code in the current source file.
This is useful when you have a global variable that you want to restrict access to, and don't want to worry about a name collision. For example, if you wanted to maintain a counter to track how many instances of a class have been created, you could create a static int gInstanceCount. Since it is static, you would know that (1) no other code can modify the variable and (2) if some other file uses a global with the same name, there won't be any collisions.
Static declarations in header files
Note that when you put something in a header file, it is as if you copied-and-pasted that code into every other file that includes it. That means if you declare something as static in a header file, every file that includes it gets its own copy of that thing.
That means if you declare static int foo in Foo.h and then write execute foo = 4 in Bar.m, when you try to access that value in Other.m you won't necessarily get 4 back.
Local static variables
You can also define a local variable (inside a function or method body) as static. Normally, local variables are allocated on the "stack" which means they are created when your function is executed and deallocated when the function exits. If two threads enter the same function at the same time (or one thread makes a recursive call back into a function) each thread gets a fresh chunk of memory to work with, and anything it does won't affect any other thread.
However, a local static variable is stored on the "heap" instead. All executions of the function share that same memory location. Also, when the function ends, the value stays where it is. That's why a local static variable is often used in sharedInstance methods on Objective-C singleton objects.
In most ways, a local static variable basically acts like a global variable that can only be seen inside the function which declared it.
the static keyword is used to provide scope to global variables. Normally, global variables defined outside of a function have a public scope, and are visible to all .m or .c files in a project. making a variable static allows you to have a "global" variable which is scoped (visible) to only the .m or .c file containing the variable definition. This allows you to have a variable which can be shared by multiple functions in a single source file, while avoiding potential naming conflicts. Also of note, the extern keyword, which allows you to indicate that a specific global variable is initialized in a different source file but used in this source file.
The keyword static is overused in C. It means several different things. In some contexts, it just means that field is only understood in the remainder of that file (compilation unit). In other words, it can't be linked to from some other file.
In Java and C++, static class members are defined at the class level, not the individual object level, so the one value is shared by all objects of that class (or one of its subclasses). Unfortunately, IMHO, Objective C does not support this. Instead you use statics at the file level.
If you don't know if you need a static variable, you probably don't need one.
One reason you might use a static variable is to provide a class variable (that is, one variable for an entire class, rather than an instance variable, which each instance of a class would have it's own copy of).
This question (and its accepted answer) explain how one would use static variables to simulate a class variable in Objective-C.
First: "object" in this context refer to "c objects", in very easy words, something, that lives at runtime. It has nothing to do with objects in the sense of OOP or Objective-C. You can think of an object as a var.
static has nothing to do with scope. static on an extern identifier (= declared outside a block) has internal linkage. The results of linkage are defined in ISO/IEC 9899:TC3, section 6.2.2. Scope is defined in section 6.2.1.
Internal linkage means, in short words, that two identifier in different translation units (".m files") do not denote the same object, but different objects. Every translation unit has its "own" object.
If an identifier is not extern (= inside a block) declared with static storage class it has a lifetime from begin of the program execution until the program stops running.
Related
After using Java for a long time I almost forgot how it is to be allowed to define global variables. I read that it is recommended to use top-level functions in Kotlin instead of wrapping them inside objects like in Scala. How about top-level variables (which I guess we call global variables)? What is the recommendation about using them? What are the pitfalls? How are they deallocated?
Global variables are supposed to be accessible from anywhere at any point in your program, so it would most likely be a bad idea to deallocate global variables, even if you could because it could lead to instability or crashes in your application.
Now Kotlin is a JVM language, it compiles to Java code and therefore is garbage-collected. As for how the garbage collector works, when a variable is no longer referenced by the program, it gets flagged for deletion and will be removed by the garbage collector later (not necessarily instantly).
Global variable's scope is the entire program so they are never garbage-collected. What could you do tho is to set its reference to null (if it is declared nullable) to allow at least the referenced memory to be collected.
The top-level variables that you are referring about aren't exactly free since Kotlin will compile them into a java class named with the file name anyway(that's how you can access kotlin file-specific functions inside java code), so they are just like static fields in Java. For a better explanation you could check this thread: Kotlin: Difference between constant in companion object and top level.
Now we know that top-level variables are compiled into static variables inside a Java class. Those don't get flagged for collection unless the program somehow drops the class loader associated to that class itself but that's something I can't speak of more since I never used that.
Now in the end, should you use global variables? They are usually considered a bad practice and this is in big part due to the fact that they can be referenced by any part of the program and it can be hard to remember when and why did they change, especially in large applications. If you keep track of their usages and use them in moderation then they are alright. Personally, if I have to use them, I define them inside a class as a companion object the same way you would define static variables in java, like this:
class GlobalData {
companion object {
var varEx= 0
const val constString = "CONSTANT GLOBAL"
}
}
Finally, when I managed to understand how to fix this, that is, how to change the value of an internal dynamic variable, the code has moved on and now it is declared in this way:
my int $is-win = Rakudo::Internals.IS-WIN;
This is a class variable declared inside class Encoding::Builtin. Makes all the sense in the world, since an OS is not something that changes during the lifetime of a variable. However, I need to test this code from other OS, so I would need to access that class variable and assign it a True value. Can I do that using the meta object protocol?
The concept of "class variable" doesn't exist in Perl 6.
The declaration being considered is of a lexical variable, and its lifetime is bound to the scope (bounded by curly braces) that it is declared within. It doesn't have any relationship with the class that's being declared, so there's no way to reach it through the MOP. (That the block in this question happens to be attached to a class declaration is incidental so far as lexical variables go.) Nor is it declared our, so it's not stored in the package either.
The only way a lexical can be accessed - aside from under a debugger - is if something inside of that lexical scope explicitly made it possible (for example, by acquiring a pseudo-package and storing it somewhere more widely visible, or by allowing EVAL of provided code). Neither is happening in this case, so the variable not possible to access.
Perl 6 is very strict about lexical scoping, and that's a very intentional part of the language design. It supports the user in understanding and refactoring the program, and the compiler in program analysis and optimization. Put another way, Perl 6 is a fairly static language when it comes to lexical things (and will likely come to do much more static analysis in future language versions), and a dynamic language when it comes to object things.
This is more of varification, but i want to be sure before i start altering some old code to clean it up.
If you have private varibales declared inside a module but outside a subroutine, when are these actually created. For example, this is how a module is set up:
'Local objects.....
'Function Main.....
'Subroutines.......
Private Constants..
Private variables..
More Subroutines...
If those variables are only used in one subroutine, should they be declared inside that subroutine or in the local objects or right outside the subroutine as they are now?
Thanks!
The CLR has no support for modules or module variables so modules become static classes and module variables become static fields.
As a rule, variables should be declared as close to the point they are used as possible. Their scope should also be as constrained as possible.
Turning a variable into a field is a pretty bad coding practice for several reasons:
It is extremely easy to make a mistake and reuse the same field in another part of your module, creating unexpected conditions.
You increase the lifetime of the objects in the variable significantly. Typically, once you exit the method, the variable is available for garbage collection. By turning it into a static field, the object will stay alive until it's replaced or the application terminates
Multiple threads will be able to see and access the same static field, potentially creating race conditions. Given how many things work asynchrously nowadays, this can be a significant problem
Static variable "Declaring a variable static limits its scope to just the class—and to just the part of the class that’s implemented in the file" (Apple doc).
And I think a variable was defined in class extension has a limit scope in just only the class define it.
That is similar !
What is different between static variable and variable in class extension ?
The static variable is tied to the file it's defined in. It's not accessible from outside of that file, and there is only one place for storage created for it in your entire program.
The distinction about storage also applies to non-static global variables -- there will only be one in your program.
A variable in a class extension is likewise limited in visibility to the file in which it's declared, but it's an instance variable. There's a new piece of storage attached to each instance of the class you create.
If you create a static variable and change its value from several instances of the class, every instance will see the same value. That is not the case with an ivar -- each object can change and retain its own value for that variable.
(This is why static variables are sometimes used in ObjC to simulate class variables, which are present in other languages.)
In objective-c, I can declare an int or bool etc in the .m file, outside any function. That allows me to use such variable everywhere in the class.
I can also declare such variables in the .h file, inside the interface block, achieving the same result.
Well, my question is: what is the difference? Is there? Or is it all a matter of organization?
In second case, it is a global variable that has external linkage. Meaning, it can be accessed other translation units / source files using extern keyword. But in first case, it is a part of interface, so it can be only used by it's member functions and any other interfaces derived from this interface depending on access specifier.
In first case they become gloabal variables in .m file and are are shared between all the instances of the interface. In second case the will be separate for multiple instances. The common way is to declare interface variables with in the interface