Can't access global array in ARC enable project - iphone

I have define NSArray using
extern NSArray *arName;
in AppDelegate method
and then assign values in Array in AppDelegate. after assign value i easily access values in AppDelegate but when I use this global array in another page control it's shows me error
i don't know the exact problem
is it any other method to define GLOBAL ARRAY ?

You'd be better off in this case using a singleton Objective-C class. Don't use global variables with anything that is derived from NSObject, or the ARC system is unable to automatically keep track of references to the object and you'll get crashes like these.

Related

Global variables?

How do I use global variables in x-code(iphone). For example, lets say i want to declare a bunch of variables(NSStrings) in the viewcontroller file, then how would i access them throughout my different classes? Can someone help me?
Global variables are global variables. You use them the same way you would in any C program, which is to say typically they'd be declared in something like "globals.h" and imported wherever needed.
With that said, it's generally poor practice to rely on globals. You might have an "ApplicationController" object which in essence tracks the global state of the application, but its variables should be instance variables and either accessed only internally, or via getters/setters.
If you wanted to declare a bunch of strings in a single object to be referenced by many other objects, typically you'd make that object a Singleton and pass a reference to it to each object needing access to it.
However, you need to ask yourself WHY you need to do that and if there isn't a better way. I'll bet dollars to doughnuts there's not a good reason for what you're trying to do.
Give us some more details on what the overriding need is for these strings to be global, and then we can show you reasons why they don't. :)
You may use a singleton if it's not too over-killed. Another option is NSDefaults. Of course, the simplest way is simply define an extern in .h
extern NSString * const STR_1;
and the value in .m:
NSString * const STR_1 = #"String One";
just declare your variables in the .h file and then import this file in any class you want to use it. You can make any type of object or variable global.
If you declare the variable in delegates, You can access those variable in any other controllers using setter and getter methods to access.
See Warrior Answer
I hope,it will help you.

Global NSMutable array of a project

I want to know how i can declare and use a global NSMutable array of an Objective C project.
I mean i need to update the here in one class and need to use in another class....
can anyone give me any kind of idea??
Thanks
Rony
Pass a reference around from class to class. Or keep a reference to the array instance in your app delegate, which you can access from any class in your application.
You could use the singleton pattern and put the array into the singleton.

Global Objects iphone

What is the easiest way to create a global object. I have tried declaring the object outside the method with no luck.
#implementation UV_TouchpadViewController;
NSMutableString *string = [NSMutableString stringWithFormat:#"text"];
Very close -- you can't initialize a non-local variable with a non-const expression, and a method call is inherently non-const, even if it looks like it should be. So basically, change it to
NSMutableString *string;
but if it's only going to be used inside the implementation file (eg. other classes would only get at it through UV_TouchpadViewController, not get/set it directly (this is also the recommended pattern)), then qualify it as static, like so
static NSMutableString *string;
If on the other hand you do want to be able to access it directly from outside UV_TouchpadViewController, leave off the static, but add
extern NSMutableString *string;
to your header file (outside the class #interface), and whomever includes the header will be able to access it. (Note that you could instead just put NSMutableString *string; in your header file, however this is quickly becomes unclear)
Also, if you are trying to do this for a singleton class, (I can't think of a good reason to have a global mutable string -- you know they're not thread safe right?) I recommend reading Apple's docs on singletons first, where they suggest you use ivars, not global variables, even for singletons. However, UV_TouchpadViewController should not even be a singleton (if it is in any way a view controller), it should just have a single instance, if that's all you want.
If on the other hand you just want all UV_TouchpadViewControllers to have access to this one variable, note that across almost all languages this is considered a bad design pattern (globals are bad), and that you should instead stick it in, say, your app delegate (which is guaranteed to have a single globally accessible instance), where it can be an ivar+accessors, and generally considered a setting and (with a little extra code) persisted.
EDIT:
If you want to have a singleton that maintains global state, which I still recommend against -- you should create a class, like for instance ApplicationState, which handles all of the application's global state as a model object in the traditional model-view-controller pattern. I wont go into detail here because that would be highly redundant of a google search.
In your Application Delegate, somewhere, add an ivar ApplicationState *state, and a corresponding #property (and #synthesize in the implementation file).
There are few easier ways to shoot yourself in the foot than by using global variables.
You should never expose a dumb object like a string which has no access control to every object in the app. Any random piece of code anywhere in the app can change the mutable string leading to chaos as the app grows larger.
Usually when people want a global variable what they actually need is either the user defaults or a data model.
The user defaults (NSUserDefaults) is the preference persistence system that saves application state and user's settings both between launches and as the app runs. You can park small bits of data, such as strings, in the defaults and access them easily from anywhere in the app.
A data model is dedicated object that holds the applications data and manages access to it such that only the data model has final control. This makes it easy to tell what has changed the data and how. The data model can be a simple custom class or something elaborate such as core date. You can park the data model in the app delegate or create it as a singleton as the other answered have explained.
I have been using the Apple API for years and I have never needed to use a real global variable. If you think you need one, you probably have misunderstood something about application design in the Apple API. You might want to post a question explaining what you're trying to do with a global variable and what the best strategy should be for doing it without the dangers of using a global variable.
Do you need it for each instance of the class? If so, you should make it an Instance variable. Put
NSMutableString *string;
In your header
And then you can set it in any method in your class.
If this isn't what you meant, update your question or comment.
You can achieve that by implementing getter and setters in the delegate class.
In delegate .h file
Include UIApplication delegate
#interface DevAppDelegate : NSObject <UIApplicationDelegate>
NSString * currentTitle;
- (void) setCurrentTitle:(NSString *) currentTitle;
- (NSString *) getCurrentTitle;
In Delegate implementation class .m
-(void) setCurrentLink:(NSString *) storydata{
currentLink = storydata;
}
-(NSString *) getCurrentLink{
if ( currentLink == nil ) {
currentLink = #"Display StoryLink";
}
return currentLink;
}
So the variable you to assess is set in the currentlink string by setters method and class where you want the string ,just use the getter method.
AppDelegate *del=(AppDelegate *)[[UIApplication sharedApplication]delegate];
TO set:
[del setCurrentLink];
TO Get:
NSString *value=[del getCurrentLink];
All the best
Add:
NSMutableString *globalString = nil;
to any .m file of any object. The nil initialization adds a little safety, since nil objects can be "safely" messaged without outright crashing the app.
Add:
extern NSMutableString *globalString;
to the headers of any other objects that needs to access this global.
Add:
if (globalString == nil) {
globalString = [ [ NSMutableString stringWithFormat:#"text"] retain ];
}
to the init of any class(es) that could be the very first to touch this global, or to some init that happens even earlier.
Globals are a less verbose form of singleton, but with no access restriction or tracking. Use with caution.
actually as per my r&d i got that by use of extern we have to create an instance but the final thing is to #define your variable and can access any where you want without any creating of instance and other thing just directly use variable by its name....

What's the best way to have functions share an array in Objective-C?

I understand that in Objective-C you declare an array in the header file and interact with it in a class. So far I'm adding things and fetching them fine within a single function. I'm new to the language however and can't figure out how to share that array across other functions.
I'd like to initialize array data in my viewDidLoad and access it from various functions later on. Is this possible and if so what's the best way to do it?
Like you said, declare the array in the view controller's header file and make it a #property. Use alloc-init in the implementation's -viewDidLoad method to set it up. Deallocate it in the dealloc method. Use its property setter (self.array) to retain or assign another array, depending on the #property attribute. Access it directly (array) throughout your methods in your class implementation, and via its property getter (obj.array) from other classes.

Should I alloc an NSMUtableArray instance variable?

This is probably a silly question but I have been thinking it over for a while with no obvious answer.
I have a small app that I have been working on and am having a problem with my NSMutableArray instance variable. It was always (null) until I added an [[NSMutableArray alloc]init] to the viewDidLoad.
I am pretty new to the Objective C world so I am trying to get an understanding of this issue. I was under the impression that with I instantiated my class the instance variables were all alloc'd. When I add items to the array without the alloc/init it remains (null) with a retain count of 0.
The array in question was declared as a (retain) property.
I can add code if this isn't clear.
Any instance variables that are objects are actually just pointers that are initialized to nil (0). That is why the item isn't retained and added to the array, since messages to nil objects return nil/0.
You need to alloc and init the object in your class's init, and then release it in the dealloc.
The retain/assign/copy qualifiers on the property declaration are about how the memory for the property value is managed in the getters and setters that the compiler synthesizes for you. (The documentation discusses them in detail, and gives example code for each kind.)
That's completely orthogonal to whether your instance variables are initialized for you or not. Declaring an ivar is just reserving storage for the value; for Objective-C classes, that's a pointer to an instance. The runtime will initialize those ivars to zero for you, but you're still responsible for creating the objects you want to store there. (The same is true in similar languages like Java or C#: declaring an Array instance variable just gives you space for a reference, it doesn't create the array for you.)