-12

It seems that Objective C jumps thru hoops to make seemingly simple tasks extremely difficult.

I simply need to create a sequence of strings, image1.jpg, image2.jpg, etc etc

ie in a loop var imgString:String='image'+i+'.jpg;

I assume a best practice is to use a NSMutableString with appendString method?

What am I doing wrong??

NSMutableString *imgString;

    for(int i=1;i<=NUMIMAGES;i++){
    imgString.appendString(@"image"+i+@".jpg");
}

I get the following error

error: request for member 'appendString' in something not a structure or union

Kamil Budziewski
  • 22,699
  • 14
  • 85
  • 105
Bachalo
  • 6,965
  • 27
  • 95
  • 189
  • 10
    Gross. Read the basic documentation on Objective-C before asking questions. It's all a lot easier than you think it is, and I assure you that it will come naturally to you once you have read the documentation. – Jonathan Sterling Jun 12 '10 at 21:27
  • 7
    The problem isn't that Objective-C makes you "jump through hoops" — it's that you haven't learned Objective-C at all. Of course it will look hard if you don't know it. You don't even have the basic syntax right — you're using Javascript method calling syntax. That's literally the second thing taught in Apple's Objective-C tutorial. I suggest you read it or you're in for surprises everywhere: http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjectiveC/Articles/ocObjectsClasses.html – Chuck Jun 12 '10 at 22:09
  • 1
    “I simply need to create a sequence of strings, image1.jpg, image2.jpg, etc etc” So then you don't need to *concatenate* strings at all. Concatenation produces a single string, which is what the code you show in your question would do if it were valid. – Peter Hosey Jun 13 '10 at 00:31
  • 1
    "What am I doing wrong?" You are trying to compile Javascript with the Objective-C compiler. – JeremyP Jun 15 '10 at 16:13

5 Answers5

38

I cannot possibly imagine how yielding the string image5image4image3image2image1.jpg in string3 in your "answer" to your own question could be construed as useful or a solution (I pasted your code into an Xcode Foundation tool project w/NUMIMAGES set to 5).

It seems that Objective C jumps thru hoops to make seemingly simple tasks extremely difficult.

Read the Objective-C Guide and the String Programming Guide, then make draw your conclusions. Criticizing something you don't understand is generally counter-productive (we've all done it, though -- easy to do when frustrated).

I simply need to create a sequence of strings, image1.jpg, image2.jpg, etc etc

Naive solution:

#define NUMIMAGES 5
NSMutableArray *fileNames = [NSMutableArray array];
for(int i = 0; i<5; i++)
    [fileNames addObject: [NSString stringWithFormat: @"image%d.jpg", i]];
NSLog(@"fileNames %@", fileNames);

Outputs:

fileNames (
    "image0.jpg",
    "image1.jpg",
    "image2.jpg",
    "image3.jpg",
    "image4.jpg"
)

Note that there isn't anything particularly wrong with the naive solution. It is just more fragile, less efficient, and more code than is necessary.

One Possible Better Solution

  1. Add all images into your application project as resources.

  2. Use the NSBundle API to grab URLs to all images at once.

I.e.:

NSArray *paths = [[NSBundle mainBundle] pathsForResourcesOfType: @"jpg" inDirectory: nil];

Not only does this remove hardcoding of image names from your code, it also allows the system to optimize directory enumeration and path generation. If you want to load only a subset of images -- say you are writing a game and have a series of images related to monsters -- then put all the related images in a single directory, add the directory to your Resources, then pass that directory's name as the second argument to the above method.

All of this -- and much more -- is documented in the resource programming guide.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • Thanks. Will have yo look it up since I'm still unclear how I would then access individual images in the paths array created. – Bachalo Jun 13 '10 at 04:53
  • 2
    NSArray documentation is quite clear and even has a companion programming guide: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Collections/Collections.html#//apple_ref/doc/uid/10000034i – bbum Jun 13 '10 at 05:28
7

First, your syntax for invoking methods is off - i recommend reading through Apples Introduction to Objective-C. Notably, to invoke a method you use the [someObject someMethod] syntax.

The next problem is that you never create the string you are trying to append to, you can use e.g. [NSMutableString string] for that.

Continuing, to concatenate a mutable string with some formatted string use -appendFormat:, e.g.:

NSMutableString *imgString = [NSMutableString string];

for (int i=1; i<=NUMIMAGES; i++) {
    if (i > 1) [imgString appendString:@", "];
    [imgString appendFormat:@"image%d.jpg", i];
}
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
2

I’m not really sure what you’re trying to do, but this might be an inspiration:

NSMutableArray *fileNames = [NSMutableArray array];
for (int i=0; i<max; i++)
    [fileNames addObject:[NSString stringWithFormat:@"image%i.jpg", i]];

As for your error, you’re using the dot syntax where it doesn’t make any sense. Also, you don’t use the + to concatenate strings in Objective-C. The correct appendString syntax looks like this:

NSMutableString *foo = [NSMutableString string];
[foo appendString:@"Hello, "];
[foo appendString:@"world!"];

As you can see on the first line, it is a good idea to initialize objects before you use them :) To concatenate strings you can use the appendString method of NSMutableString or you can create a new immutable string:

NSString *one = @"Hello, ";
NSString *two = [one stringByAppendingString:@"world!"];

If you have more strings to concatenate, you can use the stringWithFormat initializer:

NSString *composed = [NSString stringWithFormat:@"%@, %@ %@!",
     @"Hello", @"Objective-C", @"world"];

If you still have the feeling that Objective-C makes certain things extremely difficult you might gain some advantage by actually learning it ;)

zoul
  • 102,279
  • 44
  • 260
  • 354
1

The simplest code which does what you want would be something like this:

NSMutableString * string = [NSMutableString string];
for (int i = 1; i <= NUMIMAGES; i++) [string appendFormat: @"image%d.jpg", i];

That's it. As you can see, appendFormat: really makes things a lot easier! But I can't figure out why you would want to do this. You'll get something like:

"image1.jpgimage2.jpgimage3.jpgimage4.jpgimage5.jpg. . ."

What are you actually trying to achieve? Dave

Stefan P.
  • 9,489
  • 6
  • 29
  • 43
Dave Jewell
  • 116
  • 1
  • 1
-7

Appreciate all the answers!
Sometimes it feels that one needs to be a masochist to be proficient in Objective C!.
Will try the above but ended up using

NSString *string1 = @"image"; 
NSString *string2; 
NSString *string3 = @".jpg"; 
NSString *incString; //*/ 

for(int i=1;i<=NUMIMAGES;i++)
{ 
 incString=[NSString stringWithFormat:@"%d",i]; 
 string2 = [string1 stringByAppendingString:incString]; 
 string3 = [string2 stringByAppendingString:string3]; 
}
Bachalo
  • 6,965
  • 27
  • 95
  • 189
  • You really ought to take a look at the `appendFormat` function, it will make your life easier. See Georg’s answer. – zoul Jun 12 '10 at 20:33
  • 15
    Sometimes I think people should first try to actually LEARN a language before saying it sucks. I'm not a masochist and still I like Objective-C a lot, because I actually put some time into learning the language before rushing to get an app in the App Store (assuming that's what you're using Objective-C for). – Douwe Maan Jun 12 '10 at 20:37
  • 1
    What Douwe said. As written, that code doesn't make sense. – bbum Jun 12 '10 at 21:08