Accessing Singleton Instance Variable in Class Methods Throws Warning? - objective-c

I've using the Objective-C singleton from here at stackoverflow.
The singleton in the class method accesses it's instance variable, which works, but throws a complie warning. How should I be doing this? Is there a way to do this without accessing the sharedInstance: in each class method?
for example here is my class method:
+ (NSString *)myClassMethods {
[instanceDateFormatter setFormat:#"MM"];
return [instanceDateFormatter stringWithDate:somedate];
}
line 2 will have the complie warning.
Thanks,
Ross

You should be using the sharedInstance: call in each class method. I guess if you really want to, you could work around it with global variables, but the right solution is as you mentioned.

Since instanceDataFormatter is an instance variable, you have to access it via a class instance -- so you'll need to go through your sharedInstance method to get it. Or, you could access it via the static singleton variable, bypassing the call to sharedInstance (however, that could break if the static variable hasn't been initialized yet).

Related

Why is init not a class method?

Why is the init method not a class method? I mean init's method body starts with an -.
Methods starting with - are instance methods as far as I know, but obviously we want to create an instance.
init is not for creating an instance; that's alloc's job (and alloc is a class method).
init is for setting up the created instance. It needs access to the new instance's ivars, and must be an instance method.

Singleton, Method & Variable

i would like just to get answer to this question, i know it is possible with variables, but with method ?
with a singleton, can i use methods + variables anywhere in my project ?
Thanks.
A singleton is nothing but a global instance of a class. Once you get the instance anywhere on your project, you're supposed to do whatever you want with it, as you would with any other class instance. Obviously, you can access it's public variables and methods.
Yes, you won't have to create an instance to access your singleton method.

Objective-C: Class vs Instance Methods?

In Objective-C, while creating any class, how do we decide whether we need to mark a method as Class method or Instance Method ?
I know the difference between the 2, but my question is how to decide the marking (+/-) for any method ?
+ denotes a class method, - denotes an instance method. You create class or instance methods where your application needs them. Should you actually know the difference between the two, and your application, then you should have no problems understanding when to use which.
I believe you don't know the differences in how they apply to your application, so here's a small primer:
You use a class method when you need to access some behaviour globally through all instances of that class. i.e., [[self class] someSpecialThing];
You also use a class method when you need a factory method; and
Everywhere else, you use an instance method.

questions about objective-c class methods

I know that class variables are declared in memory (as opposed to on the stack) when the class is initialized, and I know how class methods are basically used. But I have some questions about class methods that aren't answered in the basic documentation.
Are class method also declared in memory? What about any object declared within these class methods? Are they 'static' in scope? What about any objects that are passed into a class method as parameter? Are those also 'static'?
Does repeatedly calling a class method mean all the objects declared within it are allocated again and again (one per method call), or are they living in one location in memory? Do they get cleared at every run?
For example, what happens to the do_something method here:
+ (void) main
{
while (i < MAX)
{
[MyClass do_something];
}
}
+ (void) do_something
{
NSMutableArray *array = [[NSMutableArray alloc] init];
...
[array release];
}
Class methods follow the same rules as object (instance) methods except you cannot access instance variables from class methods, obviously because ivars get allocated per object instance.
In your example "array" is allocated on heap with each call, as usual.
All variables are stored "in memory", no matter their storage type (static, automatic, free store), location (stack or heap), linkage or scope. A variable is static only if it's declared static. Otherwise, variables in class methods, whether parameters or local variables, have function or local scope, automatic storage, no linkage and are stored on the stack.
Class methods have global scope and external linkage, though you can send a message to an object (including classes) even if there isn't a handler in scope. Internal linkage should be possible, but I don't think the language supports declaring methods with internal linkage. Storage type and location doesn't really apply to methods, but you could say methods have static storage.
When calling the +(void) do_something method the array object will be initialised, as your code specifies, every time. It is only declared the scope of that method.
You can declare static variables in the class scope. These, as you'd expect, are accessible to all instances and class (aka static) methods.
See: http://www.otierney.net/objective-c.html#class

#synchronized in a static method

In Objective-C, you can declare a block as being synchronized on some object by using the #synchronized construct. It would look something like this:
#synchronized (self) {
// Do something useful
}
However, I'm curious what exactly self is referring to when you have a static method (+ instead of -). I tried looking through the Apple docs, and they allude to it being OK, but don't really explain it. I know it works, I'm just curious what it means.
self inside of a class (static) method refers to the class object.
In Objective-C self is determined by context. In an instance method, that would be the instance being called. In a static method, it would be the class object itself (i.e. the result of [self class] in an instance method)
With the answers above, just keep in mind that if one thread calls an instance method using #synchronized (self), and another thread calls a class method using #synchronized (self), no synchronisation will happen between the two calls, because they are using different objects for synchronisation.