Using objects in a for loop gives an error at compile

Discussion in 'Mac Programming' started by LoveMyMac2004, Aug 18, 2008.

  1. LoveMyMac2004 macrumors newbie

    Joined:
    Aug 18, 2008
    Location:
    Myrtle Beach, SC
    #1
    Hi all,

    First of all I am new to programming in XCode and Cocoa but not new to programming. I do know C/C++, and have developed applications for MS Windows using VS and VB, and on the Mac using RB. I started reading the book "Cocoa Programming for Mac OS X - 3rd Edition" and got to a point when the example program will not compile. Please bear with me since I am new to XCode. I am on Mac OS X 10.4.11 and using XCode 2.5. This is the lastest release for 10.4 according to Apple.

    Here is the code snippet:
    Code:
    	NSMutableArray *array;
    	array = [[NSMutableArray alloc] init];
    	int i;
    	for (i=0; i < 10; i++)
    	{
    		// Create a date/time object that is 'i' weeks from now
    		NSCalendarDate *iWeeksFromNow;
    		iWeeksFromNow = [now dateByAddingYears:0
    										months:0
    										  days:(i * 7)
    										 hours:0
    									   minutes:0
    									   seconds:0];
    		
    		// Create a new instance of LotteryEntry
    		LotteryEntry *newEntry = [[LotteryEntry alloc] init];
    		[newEntry prepareRandomNumbers];
    		[newEntry setEntryDate:iWeeksFromNow];
    		// Add the LotteryEntry object to the array
    		[array addObject:newEntry];
    	}
    
    	for (LotteryEntry *entryToPrint in array)
    	{
    		// Display its contents
    		NSLog(@"%@", entryToPrint);
    	}
    
    So far from what I can understand from this example is that it appears that a for loop can enumerate an array of objects like For-With loops in VB/RB. Or at least that is my understanding.

    The errors occur on the second for statement. I get these errors:

    error: nested functions are disabled, use -fnested-functions to re-enable
    error: syntax error before 'in'

    The obvious thing to me was to comment out the whole second for statement and see if it compiled, which it does. I cannot figure out what the problem is or how to change the switch when it compiles.

    There were 2 warnings, but I figured like any other C compiler warnings that these may be a result of the initial errors.

    Any help will greatly further my understanding. So far what I have seen in objective-c, I really like it more than C++. Coming from REALbasic and VB this is great so far. I think I can change the for() loop to use a regular index and parse through the array in a standard fashion.

    I would like to understand why I am getting the error. I am assuming, of course, that the code in the book is correct since I could not find any corrections to the book at the web site, which is where I first looked.

    Thank you in advance.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    1) Please wrap your code in code tags like [ code ] [ /code ] (without the spaces).

    2) I think that fast enumeration like you have used at the bottom is only available in Objective-C 2.0 which was introduced with Leopard (OSX 10.5).
     
  3. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #3
    Fast Enumeration is an Objective-C 2.0-only feature:
    http://developer.apple.com/document.../ObjectiveC/Articles/chapter_8_section_1.html

    For Objective-C 1.0 you have to use an iterator in a while loop, or some other means of looping. Fast Enumeration (and related syntax like for-each, for-in, etc.) is rad and is a great language features, it's just too bad if you're using or targeting 10.4 or below you can't use it.

    -Lee
     
  4. LoveMyMac2004 thread starter macrumors newbie

    Joined:
    Aug 18, 2008
    Location:
    Myrtle Beach, SC
    #4
    Thank for your reply. And for the help with posting code.

    So have said that, I must be using Objective-C 1.0? Well that makes more sense now. Is there any non 2.0 way of doing the same thing? I don't see myself moving to Leopard anytime real soon. And for learning purposes, do I take the book back? Or just continue and when something doesn't work chalk it up to its a 2.0 feature?

    In the mean time, I guess I can just do the following and it should give the same result:
    Code:
       for(i=0; i<10; i++)
       {
             NSLog(@"%@", [array objectAtIndex:i]);
       }
    
    I hope that is right. Well finding things like this will help me learn more.

    Thanks again.
     
  5. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    There is no 1.0 way of getting fast-enumeration. The code you posted is the 1.0 way of doing it. There are very few language changes to 2.0. From memory they are: Garbage Collection, properties and fast-enumeration. You can see the Apple warning about this at the start of the Apple Obj-C 2.0 document.
     
  6. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    Better to use the NSArray method -count than a fixed value. Unfortunately NSMutableArray can be changed, so this means the conditional isn't fixed, but there's not much to do about this other than be sure you don't modify array while in your loop. It would be something like:
    Code:
      for(idx = 0; idx < [array count]; idx++) {
        NSLog(@"%@", [array objectAtIndex:idx]);
      }
    
    -Lee
     
  7. LoveMyMac2004 thread starter macrumors newbie

    Joined:
    Aug 18, 2008
    Location:
    Myrtle Beach, SC
    #7
    Thank you. If lets say I removed an item from the array in the loop, would the -count still work in the loop? I realize that there are more things to do if an array item is removed (such as keeping the index from advancing to not skip over the next index etc).

    Hey! I think I am learning! :D

    Thanks again!
    -Don
     
  8. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    Yes. The loop is just standard C so the termination conditions get evaluated every time through the loop. So the call to count will be executed every time through the loop.

    This means if you know that the array will not change in the loop then it's more efficient to store the count in a variable and use that in the condition like this:

    Code:
    int i, count = [array count]
    for (i=0;i<count;i++)
    {
      NSLog(@"%@", [array objectAtIndex:id]);
    }
    
     
  9. LoveMyMac2004 thread starter macrumors newbie

    Joined:
    Aug 18, 2008
    Location:
    Myrtle Beach, SC
    #9
    Cool! Well thank you for the help. I am really liking objective-c the more I learn. Again thanks. Well as I progress through the book, I am sure that I may have more questions.

    I do have a goal for learning all this. Not just to learn a new programming tool, but really learn and produce some Mac software. Not that RB does not have its pros. There are things I have been trying to do in RB that I have been stuck on and cannot get a good solution for.

    Thanks again! And I know I will be asking more questions. Hopefully not anytime soon though.

    -Don
     
  10. Captain-Fungi macrumors member

    Joined:
    Oct 20, 2007
    #10
    I am having the same error as the OP using the same code/book.

    The only diference is that I am running xcode3 on Leopard. Is it the case that I am coding in Objective-C 1.0 and not 2.0? If so how do I switch to 2.0?
     
  11. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #11
    What is your target OS set to?
     
  12. Captain-Fungi macrumors member

    Joined:
    Oct 20, 2007
    #12
    Not sure, how can I check? I did just notice I am only running Xcode 2.5, I am downloading the latest version now.
     
  13. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #13
    Well if you were running XCode 2.5 you'll have had the old version of the compiler so that will be the problem. New XCode + new compiler should fix it.
     

Share This Page