How to make a Global Array? - iphone

So, I read this post, and it's pretty much exactly what I was looking for. However... it doesn't work. I guess I'm not going to go with the singleton object, but rather making the array in either a Global.h file, or insert it into the _Prefix file.
Both times I do that though, I get the error:
Expected specifier-qualifier-list before 'static'
and it doesn't work. So... I'm not sure how to get it to work, I can remove extern and it works, but I feel like I need that to make it a constant.
The end goal is to have this Mutable Array be accessible from any object or any file in my project. Help would be appreciated!
This is the code for my Globals.h file:
#import <Foundation/Foundation.h>
static extern NSMutableArray * myGlobalArray;
I don't think I need anything in the implementation file. If I were to put that in the prefix file, the error was the same.
EDIT
So, I removed the .m file from Globals, and I just have the code about in Globals.h. Assuming I am going to continue with this terrible practice of having global variables (I know it's bad, I just want to test this out), I now have a new error. It says:
"Multiple storage classes in declaration specifiers"
If I remove "extern" it works and if I remove "static" it works, but having both doesn't... what now?
****Double Edit****
Aright, so I've tried adding the array to my UIApplication Delegate, but I'm doing it wrong because it isn't working. Could someone give me some example code as to where to place it an access it? I don't know if it should go in the implementation, or somewhere else, and once the array is initialized how to access it from the other files... Do I set a new variable to the array, or something?

Just a general programming suggestion--don't share an array. You have no control over it and it will be virtually impossible to trace if something changes it at a time and in a way you aren't expecting.
Instead, create an object with the array inside it and make that object a singleton (or better yet, make a factory for it).
Whenever you want to modify your array, call methods on the object to do so. If you do this, I bet you will find a lot of redundant code you can factor into this object (for instance, searching the array for a value--make a "search" method in the object instead and pass in a value).
It may seem like a lot of work you shouldn't have to do, but you'll find it's fairly fun work, and you should find that you DO have to do it once you see how much code belongs in this object...

Just add the array as a property of the application delegate, and access it like:
[[UIApplication sharedApplication] myArray];

The two (main) ways of making an array global are separate -- either you have a class with a method
static NSMutableArray *foo;
+(NSMutableArray *)foo {
return foo;
}
(in the .m file) with the static piece NOT in the header file, or just
static extern NSMutableArray * myGlobalArray;
with out the singleton wrapper (which I think is better as it saves you from having an extra bit of unnecessary code)
Either way, it is still a bad practice that I would try to avoid.

In general, the presence of a "Globals.h" file is a bad smell that there's an antipattern at work.
I would even advise against Bill K's advice and not use a Singleton pattern at all.
Instead, create the array in your app delegate, and pass it to your root view controller(s), and along the hierarchy to the components that need access to it.

This is what I was looking for:
http://derekneely.com/tag/app-delegate/
Thank you for pointing me in the right direction!

#import <Foundation/Foundation.h>
static extern NSMutableArray * myGlobalArray;
#interface Globals : NSObject {
}
#end

Related

Where to put "extra" implementation?

Occationaly I see snippets of code creating new methods for objects and such that looks like this:
#implementation UIImage (Extras)
- (void)aMethod:(id)anObject {
// some functionality
}
#end
Where do I put this code? Do I put it in the class I'm currently writing code for? If so at what point in the code do I need to put this?
Thank you.
You can put this category code whereever you like. In general, this code should be in a file called UIImage+Extras.m and a matching header file UIImage+Extras.h.
This is an Objective-C feature known as a "category". See these articles for more info:
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html
http://macdevelopertips.com/objective-c/objective-c-categories.html
For the sake of simplicity and to keep code clean I usually put class categories in separate files.
But in general I think you just need to declare your category in some header and import it to let compiler know about methods you add. Implementation of those methods can be put in any (implementation) file, but once again I think it is better to keep it in separate place.

how to declare a variable as extern in objectivec,so that i can access that in any view controller

i want to access the same variable in all view controllers ....
extern is a C keyword, and works the same in Objective-C as in straight C. In your header file, declare your variable:
extern NSString *myGlobal;
And then set it in your .m file.
However, this is frequently a poor coding practice; it is generally preferable to explicitly hand your view controllers some kind of state object or data source.
Instead of putting in an extern for variables, store your data in the AppDelegate instance - or in some other singleton. Then you can get to it, and modify it, from anywhere.
While I'll admit I still use the AppDelegate solution quite often, I believe the singleton design pattern is a better solution. Here's a link to a solution and the reasoning.

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.

What does this -> symbol mean?

I'm a little bit confused now after I've seen a code snippet for iPhone SDK which makes use of -> rather than dot notation. It looks a lot like PHP but it does work on the iPhone. Can someone explain what's up with ->, is that some deep C-secret I should know about?
Example:
- (void)setFileURLs: (NSArray*)elements {
if (self->fileURLs != elements)
fileURLs is an instance variable or property, like so:
#property(nonatomic, retain) NSArray *fileURLs;
and there's an #synthesize for fileURLs.
Now what I think this is: Because this is the setter method for fileURLs, it would be bad to use dot notation to access the instance variable. In fact, when I do it, the application crashes. That is because it calls itself over and over again, since the dot notation accesses the accessor method and not the ivar directly. But -> will access the ivar directly.
If that's right, the question changes a little bit: Why then write "self->fileURLs" and not just "fileURLs"? What's the point of adding that self-> overhead in front of it? Does it make sense? Why?
a->b is just another way for writing (*a).b. This is a way for accessing fields of a structure or instance variables of an object that are referenced by a pointer.
See section "Other operators" at:
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
Since self is a pointer, you have to use -> and not . to access its members. Prepending the self reference to fileURLs is probably just a coding style used by the author (equivalent to writing this.member).

Use NSString in a different file then one it's created in

How can I use an NSString in a file where that string wasn't created?
ex.
I created a string in thisone.m, but I want to use the same sting (ie the same data) in thatone.m
the data from this string will be coming from a UITextField
If you don't have access to the thisone object, you can store the string as a ThisOne class variable, as long as you don't need a different one for each of your objects. Put the in your class (not inside a method, but outside of the #implementation)
extern BOOL theString;
The access is by
[ThisOne theString];
This is not as good as ennuikiller's answer, but it might be what you need.
I'm not sure exactly what your asking but there are many ways to share data between files (or objects). You can define it as an instance variable in one class and take a reference to the object instance in other class. You can pass the data to a method called on the other object, or you can share it as a global variable by making it an instance variable of UIApplication.
Again, without being more specific in your question, this should get you thinking along the right path.
As a simple example:
#interface MyObject : NSObject {
NSString *mystring;
}
I know some people don't like #define's, but they work well for this old-school C programmer.
In each project, I have a file "Strings.h" which contains a bunch of #define's, such as:
#define SK_String_I_Want_To_Display #"String I Want To Display"
(where SK_ is my preface to indicate "string constant".)
For localization, I have another file called "LocalStrings.h" with strings like:
#define SK_LOCAL(a) NSLocalizedString(#a, "") // keeps string defs simple
#define SK_Localized_String SK_LOCAL("Localized String")
#define SK_Another_String SK_LOCAL("Another String")
Then I just #import "Strings.h" or "LocalStrings.h" where needed. Because I have all localized strings in one file it's easy to make sure I have localized everything.
The biggest issue with this approach is that you have to be careful not to do something like this:
#define SK_Another_String SK_LOCAL("Another String");
--- as that semicolon at the end can cause tricky bugs that are hard to find.
The overhead of having the #define expanded in place is pretty low. Compiles take a bit longer if you change one of these .h files, but I find the solution works well.