Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

roeik

macrumors member
Original poster
Dec 25, 2008
80
0
Hi Guys,

I am trying to figure out what would be the best way to have a constant array accessible from my entire project.

I currently have a constant.h file in my project, where i define all the constants and use it throughout the project. (like in UICatalog).

Would it be possible to add a constant array there initialized from a file? The file is just a txt file with one word in each line.

thanks for your help.
 
Personally (and I already know people will say this is a bad idea) I'd create a singleton class that encapsulates the data. The first time the shared instance is requested I'd load and parse the data from a text file into an array.
 
well, is there a way to initialize it in the constant.h file?

Also what would be the proper statement to to declare an array of NSStrings?
I have 30 values so I guess I can just type them in the code, but it will be way easier if I can just initialize it from a file.

Thanks for your help.
 
As I said I would make a proper object: .h and .m files. You can create an array of pointers to any Objective-C object type using normal C syntax, although the more Objective-C/Cocoa way would be to use an NSArray which, if the content is truly static, you can initialise using the obvious method in the documentation.
 
right, this is how I normally initialize an array in the .m file in code.
But is there a way to just declare a const array in .h files? (for my case in constant.h file).

In c for example, I would just declare int list[5] = {1,2,3,4,5};

But I can't just put the arrayWithObjects function in the constants.h file.
 
right, this is how I normally initialize an array in the .m file in code.
But is there a way to just declare a const array in .h files? (for my case in constant.h file).

In c for example, I would just declare int list[5] = {1,2,3,4,5};

But I can't just put the arrayWithObjects function in the constants.h file.

What prevents you doing:
Code:
NSString *strings[5] = {@"I",@"can",@"use",@"C",@"constructs"};

This is not an NSArray, but it is a (non const) array of NSStrings. I made it non-const as your int example is non-const.
 
Also what would be the proper statement to to declare an array of NSStrings?
I have 30 values so I guess I can just type them in the code, but it will be way easier if I can just initialize it from a file.

How often does your file of 30 strings change? If the answer is "Never", then a simple copy and paste of the text into a header file, followed by some repetitive but simple editing should suffice. The result will be a header file with the strings in source-code form (quoted, with commas, etc.).

If your file of 30 strings changes regularly, then you should consider a production tool that transforms the original text file into the form of a source file.

For example, consider this list of words:
Code:
sun
shining
sea
with
might

Next, consider what the source form of the array would be:
Code:
NSString *strings[] = {
@"sun",
@"shining",
@"sea",
@"with",
@"might"
};

To get that form, we need to add the variable declaration and opening brace (prologue), then list of @-quoted words, then add the trailing brace and semicolon (epilogue).

Any programming language could be used to produce the source form from the original text, but the 'awk' command is designed for just such tasks.

The middle part, listing @-quoted words, can be done like this:
Code:
awk '{ printf "@\"%s\",\n", $0 }' words.txt >wordsAsSource.m

We could also use awk to produce the prologue and epilogue, but I'll use 'echo' instead. The whole sequence of commands is then:
Code:
echo >wordsAsSource.m '#import <Foundation/Foundation.h>'
echo >>wordsAsSource.m 'NSString *strings[] = {'
awk >>wordsAsSource.m '{ printf "@\"%s\",\n", $0 }' words.txt
echo >>wordsAsSource.m '};'

You can copy and paste that into Terminal, or you can make a shell script, or you can add a Shell Script Build Phase to your Xcode project.
 
What prevents you doing:
Code:
NSString *strings[5] = {@"I",@"can",@"use",@"C",@"constructs"};

This is not an NSArray, but it is a (non const) array of NSStrings. I made it non-const as your int example is non-const.

well, this wouldn't compile on .h file. But if you add "static const" before it will.

Code:
static const NSString *strings[3] = {@"value",@"value",@"value"};
 
well, this wouldn't compile on .h file. But if you add "static const" before it will.

Code:
static const NSString *strings[3] = {@"value",@"value",@"value"};

It was probably left as an exercise for the interested reader.


Also, you might want to read up on exactly what the static keyword does. As given, if you include the .h file in different source files, then each file that includes it gets its own private copy of the array. If one of your goals is to not duplicate things unnecessarily, then using static will work against that goal.

wordy.h:
Code:
#import <Foundation/Foundation.h>
static const NSString *strings[] = 
  { @"sun", @"shining", @"sea", @"with", @"might", };

wordy.m:
Code:
#import "wordy.h"

extern NSString ** wordy2();

int main (int argc, const char * argv[])
{
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  
  NSLog( @"main strings: %p", strings );
  NSLog( @"wordy2 strings: %p", wordy2() );
  
  [pool drain];
  return 0;
}

wordy2.m:
Code:
#import "wordy.h"

NSString ** wordy2()
{  return strings;  }

Commands & output:
Code:
gcc wordy.m wordy2.m -framework Foundation
./a.out
2010-02-05 15:09:23.656 a.out[21710] main strings: 0x3010
2010-02-05 15:09:23.657 a.out[21710] wordy2 strings: 0x3024
 
How often does your file of 30 strings change? If the answer is "Never", then a simple copy and paste of the text into a header file, followed by some repetitive but simple editing should suffice. The result will be a header file with the strings in source-code form (quoted, with commas, etc.).

If your file of 30 strings changes regularly, then you should consider a production tool that transforms the original text file into the form of a source file.

For example, consider this list of words:
Code:
sun
shining
sea
with
might

Next, consider what the source form of the array would be:
Code:
NSString *strings[] = {
@"sun",
@"shining",
@"sea",
@"with",
@"might"
};

To get that form, we need to add the variable declaration and opening brace (prologue), then list of @-quoted words, then add the trailing brace and semicolon (epilogue).

Any programming language could be used to produce the source form from the original text, but the 'awk' command is designed for just such tasks.

The middle part, listing @-quoted words, can be done like this:
Code:
awk '{ printf "@\"%s\",\n", $0 }' words.txt >wordsAsSource.m

We could also use awk to produce the prologue and epilogue, but I'll use 'echo' instead. The whole sequence of commands is then:
Code:
echo >wordsAsSource.m '#import <Foundation/Foundation.h>'
echo >>wordsAsSource.m 'NSString *strings[] = {'
awk >>wordsAsSource.m '{ printf "@\"%s\",\n", $0 }' words.txt
echo >>wordsAsSource.m '};'

You can copy and paste that into Terminal, or you can make a shell script, or you can add a Shell Script Build Phase to your Xcode project.


I just used your suggestions with the awk command. Works like magic!!!
Thanks!

Since my list of values will probably not't change very often i don't need to make a shell script build phase, but it's great to know this option exists.

Thank you for your help.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.