开发者

What's wrong with and extern NSMutableArray?

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!


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];


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.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜