views:

67

answers:

4

Hi Guys!

So I've been doing a lot of reading. And I have been able to finally declare an extern MutableArray and access it from different Views. I have two views: 1) Testing View Controller 2) Test2

I declare the array as follows: TestingViewController.h

extern NSMutableArray *myArray;

#import <UIKit/UIKit.h>

@interface TestingViewController : UIViewController {

}

I initialize the array when the TestingViewController Loads. Then I can add Objects to it from Test 2 as Follows: Test2.m

#import "Test2.h"

NSMutableArray *myArray;
@implementation Test2

-(IBAction)addToArray{
 [myArray addObject:@"Hot like Mexico"];
 NSLog(@"Object was added to Array! Count: %d",[myArray count]);
}

It seems to be working from both Views. The count and Objects are consistant even while switching.

What I want to know is, what is wrong with this? I know a lot of experienced programmers hate global variables, but the only way I've gotten it to work is like above and through the AppDelegate (Don't want to do it that way). Just trying to be more efficient with adding and manipulating arrays from multiple Views.

Thank you guys!

+1  A: 

The problem with global variables is that they proliferate. First you have one, then you need another one, and before you know it, you've got dozens of global variables, you're not sure where variables get initialized and freed, and every change takes forever, because you don't know what the dependencies between components are.

Typically, you'll want to have an identified owner for each resource in the program. In a Cocoa app, the various controller and delegate objects provide a natural hierarchy of responsibility for various parts of the design.


For the specific case where you have an object which you need to be accessible in several views of your app, You'd typically make that object available through a method of your view controller class, then ensure that each view has a reference back to the controller.

For an example, look at any of the examples for UITableView. There is a fairly complicated data source protocol used there, but other UIKit classes have a "delegate" property which typically gets initialized to an object that manages some part of their state for them.

Mark Bessey
What would you recommend doing if you just need an array that can be accessed from any view in your app? I've yet to see a working example with code : \
Antonio
How do I establish a method in my view controller that can be accessed from another class, and have a reference to it from different views?
Antonio
+1  A: 

Global variables are nightmares when it come to memory management, and this really isn't the typical way to do things in terms of design. The proper way to do it would be to declare myArray as a property in TestingViewController and then access that property from Test2.

macatomy
How do you manage this? Theoretically I think you'd have to create an object of the TestingViewController class in Test2 and somehow access it from Test2. Can you provide some sample code I can look at ?
Antonio
If you create a TestViewController and a Test2 object in the NIB in Interface Builder, you can just use an IBOutlet to the TestViewController from Test2 and just link that up.
macatomy
+1  A: 

If you really need a "global" object, here's a simple pattern that I use quite a lot - well, not a lot, because I don't tend to have many globals.

Decide which class you want it to belong to. Let's say Test2 is the logical class to put it in. Create a method in Test2 to access the variable. (could be a class method or an instance method) as follows:

@interface Test2 : NSObject
{
    // ivars
}

+(NSMutableArray*) myArray;  // could also be an instance method

@end

@implementation Test2

+(NSMutableArray*) myArray
{
    static NSMutableArray* theValue = nil;
    @synchronized([Test2 class]) // in a single threaded app you can omit the sync block
    {
        if (theValue == nil)
        {
            theValue = [[NSMutableArray alloc] init];
        }
    }
    return theValue;
}
@end

Edit: Using the class method, to access myArray from anywhere just do this:

#import "Test2.h"

// To use class method, send messages to the class itself

[[Test2 myArray] addObject: @"foo bar"];
id foo = [[Test2 myArray] objectAtIndex: 0];
JeremyP
How would I access myArray from TestViewController or from another view?
Antonio
See edit above.
JeremyP
+1  A: 

Sounds like you need a singleton. http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html

hi there