Objective C: store variables accessible in all views - iphone

Greetings,
I'm trying to write my first iPhone app. I have the need to be able to access data in all views. The data is stored when the user logs in and needs to be available to all views thereafter.
I'd like to create a static class, however I when I try to access the static class, my application crashes with no output on the console.
Is the only way to write data to file? Or is there another cleaner solution that I haven't thought of?
Many thanks in advance,

Use a singleton class, I use them all the time for global data manager classes that need to be accessible from anywhere inside the application. You can create a simple one like this:
#interface NewsArchiveManager : NetworkDataManager
{
}
+ (NewsArchiveManager *) sharedInstance;
#end
#implementation NewsArchiveManager
- (id) init
{
self = [super init];
if ( self )
{
// custom initialization goes here
}
return self;
}
+ (NewsArchiveManager *) sharedInstance
{
static NewsArchiveManager *g_instance = nil;
if ( g_instance == nil )
{
g_instance = [[self alloc] init];
}
return g_instance;
}
- (void) dealloc
{
[super dealloc];
}
#end

I don't know what you mean with "static class", but what you want is a singleton. See this question for various methods on how to set one up.

Related

method name part of same singleton class?

I have a class, in that class I have set up a singleton patter and have a method, here is a short example of what it looks like.
#pragma mark Singleton Methods
+ (id)sharedManager {
#synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
//so some init stuff here
//...
}
-(void)savemethod {
//etc etc
}
I'm wondering if I am to call/initalize the singleton class to be used like so
//set up plist controller class as a singleton so that you dont loose cache numbers etc
EnginePropertiesController *enginePC = [EnginePropertiesController sharedManager];
then later on in the same class where I have initialized the singleton I call the save method...
[enginePC saveMethod];
So what im wondering is saveMethod part of the same instance? I think it is because i am using the same initialization name enginePC.. but would like some clarification on this.
If I'm understanding you, you are correct that saveMethod would be called on the singleton instance. What you name a pointer has no bearing on what it points to.

universal array in objective C

I am making my first app, and already made it on android, and am now trying to make it on iphone, but have no objective c experience. The app is super simple except for one part, the array.
The app has a button, that when pressed, needs to store info into an array. The problem I am running into is that when I create the array in the method where the button-click actions take place, every time I click the button it creates a new array, defeating the point of the array. When I make the array outside of the method, it either doesn't pass into the method (error says undefined) or, when I declare the object in the .h file, the program compiles, but when I hit the button it crashes.
Any help would be greatly appreciated. Examples would be great, but even if someone could point me in the right direction of things to look up, that would save me from going bald.
Try something like this (this isn't ARC) -
#interface MyViewController : UIViewController {
NSMutableArray *myArray;
}
#implementation MyViewController
-(id)init {
self = [super init];
if (self) {
myArray = [[NSMutableArray alloc] init];
}
return self;
}
-(void)dealloc {
[myArray release];
[super dealloc];
}
-(IBAction)buttonPressed {
[myArray addObject:someObject];
}
#end
You need to declare your array as an instance variable (AKA "ivar") inside the curly braces section of the the interface declaration in your .h file, and also initialize it in your designated initializer.
In the .h file:
#interface MyClass : NSObject {
NSMutableArray *myArray
}
// methods
#end
In the .m file:
-(id)init {
self = [super init];
if (self) {
myArray = [NSMutableArray array];
}
return self;
}
Now you can use myArray in all instance methods of your class.
EDIT: This sample assumes that you are using automated reference counting. Since this is your first app, using ARC is a good idea (XCode asks you if you would like to use it when you create a new project).

How to Implement a Global Static Class

This is kind of newbie question on objective-c:
I would like to create a static class available throughout my entire code to be accessed by any object. This class will act as a container of several objects.
Can anybody provide a short example of code as how to declare static global variables and methods ?
For my Globals class I have something like this
The .h file looks like this
#interface Globals : NSObject
{
}
+ (Globals *)instance;
#end
and the .m file is like this
import "Globals.h"
#implementation Globals
- (id)init
{
self = [super init];
if (self)
{
}
return self;
}
+ (Globals *)instance
{
static Globals *instance = nil;
#synchronized(self)
{
if (instance == nil)
{
instance = [[Globals alloc] init];
}
}
return instance;
}
- (void)dealloc
{
[super dealloc];
}
#end
of course this is a very basic example of a Globals class
you should think of it making as Singleton class,
Find below the some link that will help you to understand Singleton pattern in Objective-C.
A note on Objective-C singletons,
Singleton Classes.,
Using the Singleton Pattern in Objective-C,
And you could also use the Factory pattern for creating objects ..
Create a class and have your app delegate hold an instance of the class -- if you really need that global visibility. Global mutable state such as global variables and singletons are bad smells. A superior solution can be thought up.

where do I instantiate my class so I can access it throughout my app?

I've been working through some objective-c/ iOS dev books and I've hit a stumbling block. I get the feeling that I'm missing something dumb here, so I'm sure you guys can help, because you're all so damn smart :-).
I've got a very simple app that consists of 1 button and 1 label. Pushing the button puts a message in the label. I've created a class that includes a method to create said message. Here is the problem:
#import "classTestViewController.h"
#implementation classTestViewController
#synthesize myLabel;
- (void)viewDidLoad
{
}
-(IBAction) pressGo:(id)sender{
MyClass * classTester = [[MyClass alloc] init];
classTester.count = 15;
NSString *newText = [classTester makeString ];
myLabel.text = newText;
}
- (void)dealloc
{
[classTester release];
[myLabel release];
[super dealloc];
}
The output of this app, in my label, is "Yay 15". So you can see the problem, the only way I can get this to work is to instantiate the class right there, in the "pressGo" method. This isn't desirable because another method can't access or change the class variable count. Also I get a warning that local declaration of classTester hides instance variable. If I move the class instantiation to the viewDidLoad method, which seems right, the other methods can't access it anymore.
#import "classTestViewController.h"
#implementation classTestViewController
#synthesize myLabel;
- (void)viewDidLoad
{
MyClass * classTester = [[MyClass alloc] init];
}
-(IBAction) pressGo:(id)sender{
classTester.count = 15;
NSString *newText = [classTester makeString ];
myLabel.text = newText;
}
- (void)dealloc
{
[classTester release];
[myLabel release];
[super dealloc];
}
The output of that is nada. If I try to access just one variable, classTester.count, for example, even after setting it, I get a 0 value. I also get the override warning here as well.
So my question is, how can i get access to that class instance throughout my app and not just in one method? I'm using a view based application.
Declare classTester in your interface file with:
#class MyClass
#interface classTestViewController : UIViewController
{
MyClass *classTester;
}
// Any other custom stuff here
#end
Then instantiate it in your viewDidLoad method with:
classTester = [[MyClass alloc] init];
And you should be able to access the ivar from any method within this class. If you want it to be accessible to your entire app, #Waqas link will point you in the right direction.
You need to create a singleton class which instantiate once and is available inside whole project
Have a look
http://projectcocoa.com/2009/10/26/objective-c-singleton-class-template/

How to save state of the app when app terminates?

I am trying to save the app state by encoding when the app terminates.
I've found the solution related this issue.
But I don't know how to use.
I am really trying to make encoding and decoding like this:
http://cocoaheads.byu.edu/wiki/nscoding
in CustomObject.h
#interface CustomObject : NSObject <NSCoding>
{
NSArray *someArray;
}
in CustomObject.m
#implementation CustomObject
// Other method implementations here
- (void) encodeWithCoder:(NSCoder*)encoder {
[encoder encodeObject:someArray forKey:#"someArray"];
}
- (id) initWithCoder:(NSCoder*)decoder {
if (self = [super init]) {
someArray = [[decoder decodeObjectForKey:#"someArray"] retain];
}
return self;
}
#end
My object to save is another NSArray. Not "someArray" in CustomObject. We call it that "MySaveObject".
I want to pass "MySaveObject" to "someArray" in CustomObject.
Actually I don't know how to encode "MySaveObject" and to pass to "someArray" in CustomObject.
Thanks in advance.
You have to make sure that the objects contained in the array are also able to be encoded. If those objects are custom objects, you'll have to implement NSCoding in them yourself.