'for' loop inconsistencies

Discussion in 'iOS Programming' started by teamstar, Mar 24, 2012.

  1. teamstar macrumors newbie

    Joined:
    Mar 24, 2012
    #1
    Hi guys,
    I set the 'for' statement to loop for 10 times but i'm not getting 10 loops. Sometimes it returns 6, at times it returns 4,3,7 etc. Only rarely did i get 10 return during runtime.
    Code:
    int y_axis = 200;
        
        for (int q = 0; q < 10; q++) {
            int rand = arc4random()%10;
            if (rand == 0) {
                NSString  *msg = @"I've got 0";
                UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
                label.text = msg;
                [scrollView addSubview:label];
                [label release];
                [msg release];
                y_axis = y_axis + 20;
            }
            if (rand == 1) {
                NSString  *msg = @"I've got 1";
                UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
                label.text = msg;
                [scrollView addSubview:label];
                [label release];
                [msg release];
                y_axis = y_axis + 20;
            }
            if (rand == 2) {
                NSString  *msg = @"I've got 2";
                UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
                label.text = msg;
                [scrollView addSubview:label];
                [label release];
                [msg release];
                y_axis = y_axis + 20;
            }
            if (rand == 3) {
                NSString  *msg = @"I've got 3";
                UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
                label.text = msg;
                [scrollView addSubview:label];
                [label release];
                [msg release];
                y_axis = y_axis + 20;
            }
            if (rand == 4) {
                NSString  *msg = @"I've got 4";
                UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
                label.text = msg;
                [scrollView addSubview:label];
                [label release];
                [msg release];
                y_axis = y_axis + 20;
            }
            
            
    
        }
    
    I've attached the screenshot of the output along.
    Thanx in advance...
     

    Attached Files:

  2. charlieegan3 macrumors 68020

    charlieegan3

    Joined:
    Feb 16, 2012
    Location:
    U.K
    #2
    hmm that is a bit puzzling.

    would changing "q < 10" to q =< 10 work.

    Also would a switch case statement be more suitable here?

    i have never done obj c programming, sorry i can't be of more help.
     
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #3
    You don't handle the cases where rand == 5, 6, 7, 8, or 9.
     
  4. teamstar thread starter macrumors newbie

    Joined:
    Mar 24, 2012
    #4
    Lol... what was i thinking...
    Thanx dejo...
     
  5. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #5
    Something you could have easily avoided with much simpler code :

    Code:
    int y_axis = 200;
        
        for (int q = 0; q < 10; q++) {
            int rand = arc4random()%10;
            NSString  *msg = [NSString stringWithFormat: @"I've got %d", rand];
            UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
            label.text = msg;
            [scrollView addSubview:label];
            [label release];
            // We shouldn't be doing this anyway : [msg release];
            y_axis += 20;
        }
    
    Or something you could have found out using the debugger (doesn't anyone use the debugger to step through code anymore ?).

    Also, why are you releasing msg ? You haven't allocated anything, it's pointing to a string literal...
     
  6. teamstar thread starter macrumors newbie

    Joined:
    Mar 24, 2012
    #6
    Unable to run

    I made some changes to the codes to just flush out the UI elements but there was error at runtime.
    Code:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	// Do any additional setup after loading the view, typically from a nib.
        CGRect scrollViewFrame = CGRectMake(0, 0, 320, 460);
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
        [self.view addSubview:scrollView];
        
        CGSize scrollViewContentSize = CGSizeMake(320, 800);
        [scrollView setContentSize:scrollViewContentSize];
        
        int y_axis = 20;
        
        for (int q = 0; q < 10; q++) {
            
            //Inserting question numbers
            UILabel *num  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
            [num setText:[NSString stringWithFormat:@"%d",q]];
            
            //Inserting questions
            UITextView *textView1 = [[UITextView alloc] init];
            [textView1 setFont:[UIFont fontWithName:@"Helvetica" size:12]];
            [textView1 setText:@"Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla"];
            [textView1 setTextColor:[UIColor blackColor]];
            [textView1 setBackgroundColor:[UIColor whiteColor]];
            [textView1 setTextAlignment:UITextAlignmentLeft];
            [textView1 setFrame:CGRectMake(20, y_axis, 300, 135)];
            [self.view addSubview:textView1];
            [textView1 release];
            
            //Add to scrollview
            [scrollView addSubview:num];
            [num release];
            [scrollView addSubview:textView1];
            [textView1 release];
            
            //Increase y_axis positioning for next question
            y_axis = y_axis + 100;
            
        }
    }
    
    
    The error is at the AppDelegate.m:
    Code:
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
        // Override point for customization after application launch.
        self.viewController = [[[scrollViewRanGen1ViewController alloc] initWithNibName:@"scrollViewRanGen1ViewController" bundle:nil] autorelease];
        self.window.rootViewController = self.viewController;
        [self.window makeKeyAndVisible];[B][COLOR="Red"]<-Thread 1:Program received signal:"EXC_BAD_ACCESS"[/COLOR][/B]
        return YES;
    }
    
    
    The thing is it only occurs when i insert the declaration of UITextView *textView1 and its properties in side the 'for' loop to replicate it 10 times. Again i apologize if this is another foolish issue.

    Thanx in advance

    ----------

    I'm really a newbie in this environment. The book that i bought is not very helpful. So while waiting for amazon to ship the recommended ones, i just dun want to wait around. I really appreciate the guides KnightWRX.

    As for the 'msg' variable, well i'm still digesting what out to be released and what's not. Again you have helped me understand that non UI elements dun need to be released (Did i get tt right?)

    Again thank you KnightWRX...
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    For a while now, I've noticed that if it's not directly shown in a book or tutorial, it doesn't happen. And honestly, when was the last time you saw a book that showed how to use the debugger?

    It's a shame, because newbies can learn a lot about visualizing the program's operation simply by stepping through it and seeing the variables change. Not even on a broken program, but a simple working known-good program. And visualizing a program's operation is the main insight that leads from pasting together inscrutable fragments of magic spells to actual comprehension of what the code means.
     
  8. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #8
    Frankly ? I don't read books on programming. :p

    But you do have a point. Maybe we should write a tutorial on how to use a debugger. They are pretty much all the same (watch variable, Step over, Step Into, Step Out, Continue, Breakpoints...).

    ----------

    Nope, you couldn't have gotten it more wrong.

    UI or non-UI has nothing to do with memory management (release, alloc, retain, autorelease).

    Code:
    NSString  *msg = [NSString stringWithString: @"I've got a string"];
    NSString  *msg = [[NSString alloc] initWithString: @"I've got a string"];
    NSString  *msg = [[[NSString alloc] initWithString: @"I've got a string"] autorelease];
    NSString  *msg = @"I've got a string";
    
    All of the above result in about the same behavior, msg now points to a string which reads "I've got a string". However, only 1 requires an explicit release.

    You need to pair allocs with releases. Some framework methods may differ from this general rule, but the documentation will be clear when they do, just make sure to read your class references correctly.
     
  9. teamstar thread starter macrumors newbie

    Joined:
    Mar 24, 2012
  10. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #10
    Yes, count your allocs vs your releases. Everything should then be clear.
     
  11. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #11
    Advanced Memory Management Guide
    Cocoa Fundamentals Guide

    ----------

    Frankly, neither do I. At least not for a long time. I'm just thinking about the last few books whose source code I looked at in order to answer a posted question.

    It's a pity that none of them seemed to have anything on actual debugging, as if everyone were expected to write perfect code the first time. Weird, when you think about it. Completely divorced from the real world. The whole concept of problem-solving strategies is completely missing. It's all about the API and following the spoon-feeding to see the pretty toys, not about strategies for making things that work.
     
  12. teamstar thread starter macrumors newbie

    Joined:
    Mar 24, 2012
    #12
    Please please please alert me if you guys decide to come up with tutorial on debugging...
     
  13. seepel macrumors 6502

    seepel

    Joined:
    Dec 22, 2009
    #13
    ok let's so simplify things shall we?

    You can format a string like you would printf, in this case let's use %d to insert an integer (read up on this it happens ALOT), now we don't need a million if statements.

    Second, only release an object that you explicitly retain/copy/new. For example

    Code:
      MyObject *mObject = [[MyObject alloc] init];
      // do something...
      [myObject release];
    
    Code:
      MyObject *mObject = [myOtherObject copy];
      // do something...
      [myObject release];
    
    And I've never actually used new so I won't give an example...
    On to the code at hand, try this...

    Code:
    int y_axis = 200;
        
    for (int q = 0; q < 10; q++) {
        int rand = arc4random()%10;
        NSString  *msg = [NSString stringWithFormat:@"I've got %d",rand];
        UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(0, y_axis, 320, 21)];
        label.text = msg;
        [scrollView addSubview:label];
        [label release];
        // as mentioned, not needed only release abc exits you init/new/copy
        //[msg release];
        //y_axis = y_axis + 20; try this instead
        y_axis += 20;
    }
    
     
  14. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #14

Share This Page