Results 1 to 13 of 13
  1. #1
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    Objective - c program help (source included)
    I am just learning objective-c. I have stephen kochan's new book on pre-order (anyone know when that should be out?) and I am just building simple programs for practice.

    I made a program that calculates the first 13 numbers of Fibonacci's sequence, but now I am trying to make the program calculate one further number in the sequence per button push and I can't figure out how to do it. Here is the code I have so far. The error I get is that the variables in the else statement are undefined. I know that variables are protected and they can't be accessed from different functions (I guess the else statement makes it a different function?) but how do I get around this problem?

    Code:
    #import "control.h"
    
    @implementation control
    - (IBAction)generate:(id)sender 
    {
    	
    	
    	if (buttonPress != 1)
    	{
    		buttonPress = 1;
    		int a = 0;
    		int b = 1;
    		int c;
    
    		NSLog(@"%d", a);	//print first 
    		NSLog(@"%d", b);	//print second
    		c = a + b;
    		NSLog(@"%d", c);	//print third
    	
    		int i;
    		for (i=0; i<=9; i++) //print #4-#13 of the sequence
    		{
    			a = b;
    			b = c;
    			c = a + b;
    			NSLog(@"%d", c);
    
    		}
    	}
    	
    	else // print one additional number in the sequence per button press
    	{
    		a = b;
    		b = c;
    		c = a + b;
    		NSLog(@"%d", c);
    	}
    	
    }
    
    @end
    edit - I found that if I initialize the variables in the @interface section it will compile but I get the warning "local declaration hides instance variable" and when you run the program the first button press gives you the first 13 numbers but every press after that gives a zero.

  2. #2
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    I got it working using setters and getters, but the compiler still gives me a bunch of warnings. I know this isn't the best code, but am I at least on the right track? The textbox outlet is there because I would like to eventually have it display the results in the app window rather than the console but for now I am just trying one thing at a time. Here is the working code, sorry for the sloppiness. Originally I setup a new class to handle the setting and getting of the variables, but for some reason it didn't work. Is that the correct way to do it?

    Code:
    #import <Cocoa/Cocoa.h>
    
    @interface control : NSObject {
        IBOutlet id textBox;
    	int a;
    	int b;
    	int c;
    	int buttonPress;
    }
    
    - (IBAction)generate:(id)sender;
    - (void) seta: (int) newNumber;
    - (void) setb: (int) newNumber;
    - (int) a;
    - (int) b;
    
    @end
    
    #import "control.h"
    
    @implementation control
    - (IBAction)generate:(id)sender 
    {
    	
    	if (buttonPress != 1)
    	{
    		buttonPress = 1;
    		int a = 0;
    		int b = 1;
    		int c;
    
    		NSLog(@"%d", a);	//print first 
    		NSLog(@"%d", b);	//print second
    		c = a + b;
    		NSLog(@"%d", c);	//print third
    	
    		int i;
    		for (i=0; i<=9; i++) //print #4-#13 of the sequence
    		{
    			a = b;
    			b = c;
    			c = a + b;
    			NSLog(@"%d", c);
    
    		}
    		[self seta: a];
    		[self setb: b];
    		[self setc: c];
    	}
    	
    	else // print one additional number in the sequence per button press
    	{
    		a = [self a];
    		b = [self b];
    		c = [self c];
    		a = b;
    		b = c;
    		c = a + b;
    		NSLog(@"%d", c);
    	}
    	
    }
    
    - (int) a
    {
    	return a;
    }
    
    - (int) b
    {
    	return b;
    }
    
    - (int) c
    {
    	return c;
    }
    
    - (void) setc: (int) newNumber
    {
    	c = newNumber;
    }
    
    
    - (void) seta: (int) newNumber
    {
    	a = newNumber;
    }
    
    - (void) setb: (int) newNumber
    {
    	b = newNumber;
    }
    
    @end

  3. #3
    Objective - c program help (source included)

    Member Since
    Mar 15, 2007
    Posts
    161
    Specs:
    17" MacBook Pro, 2.33GHz C2D, 2GB RAM
    You've got a lot of issues in this code that I don't have time to dig through, but I will at least tell you that the undefined variable errors in the earlier version of the code were because your declarations of variables a, b and c were scoped to the first part of the "if" statement. (No, the "else" doesn't make it part of a different function.) Since you also wanted to use the same variables in the "else" part, the most likely approach would have been for you to move the declarations to before the "if" statement (so that you would be using the same variables in both places).

    In the 2nd version of the code, you've got namespace confusion from using the same variable names (a, b, c) as locals within your "generate" function and also as instance variables of the class object (leading to the "local definition hides instance variable" error you mentioned). This is never a good idea, as can be seen in the "else" portion of your code shown here, where you may think you are assigning values to the locals from the instance variable accessor methods, but in fact you are using the accessor methods to get values for the instance variables and are immediately storing the values right back into the same instance variables they came from (and without using the mutator methods for the latter task).

    Beyond these fundamental issues, you're also not really on the right track for making a program that responds to a button press to perform additional work. You may want to wait until you have that book in hand before going any further, so that you don't keep going further down the wrong road and accumulating more stuff that you'll only need to unlearn eventually. Or if you don't want to wait, then find some more online Obj-C tutorials and start going through those.

  4. #4
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    Thank you for you help. Could you quickly tell me how it should be done? I am not asking for code, but just in english. It seems to me that if I just move the variable declarations outside the if statement the first code is very close to working, but then the buttonPress check doesn't work for some reason.

  5. #5
    Objective - c program help (source included)

    Member Since
    Mar 15, 2007
    Posts
    161
    Specs:
    17" MacBook Pro, 2.33GHz C2D, 2GB RAM
    Given how you have structured your code, you do need persistent instance values rather than local variables in order to keep around the current sequence data values for calculating subsequent values on subsequent button pushes. Since they are only used internally, you don't really need accessor and mutator methods. I'd define a, b, and c as instance variables (although I'd probably choose more descriptive names) and then use them directly in the Fibonacci calculations, with no automatic (local) variables at all. The value of buttonPress also needs to be persistent, either as an instance variable (as in your 2nd example) or as a static local variable in the generate method.

    I would suggest restructuring things to at least move the Fibonacci calculations out of generate and into a separate method (perhaps named something like getNextFibonacciValue) that simply calculates the next value in the sequence. Your generate method would then call getNextFibonacciValue, in order to keep the Fibonacci calculation in exactly one unique place. Duplication of algorithmic code in multiple locations invites problems in any non-trivial program, so it's wise to get used to designing your code that way from the outset. In fact I'd go further and say that the code and persistent values for the Fibonacci algorithm belong in a separate class object that is composited into the controller class, which hides its internal data (a, b, and c) and just provides the next Fibonacci number as a return value from getNextFibonacciValue, since the generate method doesn't really need to know anything more than that.

    EDIT: This is short enough that I'll whip up some code to make it clearer, so stop reading now if you want to try it yourself first. Notice that the restructured code is quite concise. I didn't create a separate Fibonacci class for this example, but it would be similar in most respects.

    Code:
    @interface appController : NSWindowController {
    	int prev1;
    	int prev2;
    	int current;
    	int seqVal;	
    }
    - (IBAction)generate:(id)sender;
    - (int)getNextFibonacciValue;
    @end
    
    @implementation appController
    - (IBAction)generate:(id)sender
    {
    	static int initialSeqShown = 0;
    	if (!initialSeqShown)
    	{
    		for (int i = 0; i < 13; ++i)
    			NSLog(@"%d", [self getNextFibonacciValue]);
    		initialSeqShown = 1;
    	}
    	else
    		NSLog(@"%d", [self getNextFibonacciValue]);
    }
    
    - (int)getNextFibonacciValue
    {
    	if (seqVal <= 1)
    		current = seqVal++;
    	else
    	{
    		prev2 = prev1;
    		prev1 = current;
    		current = prev1 + prev2;		
    	}
    	return current;
    }
    @end

  6. #6
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    Thanks a lot for your help. This is what I came up with. I changed it a little so that it generates one number in the sequence per button press rather than generating the first 13 with one press.

    Code:
    #import <Cocoa/Cocoa.h>
    
    
    @interface control : NSObject {
        IBOutlet id textBox;
    	int a;
    	int b;
    	int c; 
    	int press;
    }
    
    - (IBAction)generate:(id)sender;
    - (int)nextNumber;
    
    @end
    
    #import "control.h"
    
    
    @implementation control
    - (IBAction)generate:(id)sender 
    {
    	NSLog(@"%d",[self nextNumber]); // print next number in fibonacci sequence
    }
    
    - (int)nextNumber
    {
    	if (!press) // for the first press return 0 because it is the first number in the sequence
    	{
    		press = 1;
    		return 0;
    	}
    	else if (press == 1) // for the second press return 1 because that is the second number in the sequence
    	{
    		press = 2;
    		return 1;
    	}
    	else if (press == 2) // for the third press set a and b equal to the first and second number in the sequence
    	{
    		press = 3;
    		a = 0;
    		b = 1;
    	}
    	else // set a and b as the most recently calculated numbers in the sequence
    	{
    		a = b;
    		b = c;
    	}
    	c = a + b; // determine next value in the sequence by adding the most recent two values
    	return c; 
    }
    
    @end
    I do have a few more questions.

    Is it okay to cut the nextNumber method short by returning values in the if statements?

    If I was going to create a seperate fibonacci class would I have to initialize and alloc an instance of that class before I use it? Then all the work would be done by a single instance of the class. Is that right?

    Rather than using NSLog to display the numbers I would like to output them using the textBox outlet. It is linked to a large text area in my GUI. I know that if I just use setStringValue it sets it to the new value and deletes the old value. Would I use a mutable string to add the new number values to the end of the string as they are created and output that?

    Sorry about all the questions. I just finished coding and havn't done any research yet. I will edit my post if I find the answers I am looking for.

    I am going to take your advice about doing tutorials for now to get a better understanding rather then trying my own projects.

    Thanks again,

    Josh

  7. #7
    Objective - c program help (source included)

    Member Since
    Mar 15, 2007
    Posts
    161
    Specs:
    17" MacBook Pro, 2.33GHz C2D, 2GB RAM
    Quote Originally Posted by JoshMcg View Post
    I do have a few more questions.

    Is it okay to cut the nextNumber method short by returning values in the if statements?
    Yes, it's okay, although I generally try to avoid it. I was taught that it is better programming form to have exactly one exit point in any function, and I try to do that whenever possible (you may have noticed I arranged things that way in my implementation of the Fibonacci function). However, it is not at all uncommon to see multiple return statements embedded in nested code within a function in order to gain a slight performance improvement, or to simplify the code that follows.

    If I was going to create a seperate fibonacci class would I have to initialize and alloc an instance of that class before I use it? Then all the work would be done by a single instance of the class. Is that right?
    It sounds like you are on the right track. Don't forget you'd need a pointer to the class as an instance variable in your controller class, e.g.:

    Code:
    #import "fibonacciGenerator.h"
    
    @interface appController : NSWindowController {
    	fibonacciGenerator *fibGen;
    }
    ...
    @implementation appController
    - (id)init
    {
    	[super init];
    	fibGen = [[fibonacciGenerator alloc] init];
    	return self;
    }
    @end
    Rather than using NSLog to display the numbers I would like to output them using the textBox outlet. It is linked to a large text area in my GUI. I know that if I just use setStringValue it sets it to the new value and deletes the old value. Would I use a mutable string to add the new number values to the end of the string as they are created and output that
    If you mean that you'd create an NSMutableString as an instance member of your controller class, and then append the next sequence value to its contents before making each call to setStringValue for the text area, then yes, that would be a reasonable approach.

  8. #8
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    Is there any way to make something like this work?

    Code:
    [list appendString:(@", %d",[self nextNumber])];
    I looked through the documentation and tried a few different things, but I can't get it.

    list is defined like this in the @interface section

    Code:
    NSMutableString *list;

  9. #9
    Objective - c program help (source included)

    Member Since
    Mar 15, 2007
    Posts
    161
    Specs:
    17" MacBook Pro, 2.33GHz C2D, 2GB RAM
    Quote Originally Posted by JoshMcg View Post
    Is there any way to make something like this work?

    Code:
    [list appendString:(@", %d",[self nextNumber])];
    Replace "appendString" with "appendFormat" as I've shown below. Note that you also had some extraneous parentheses which I've removed:

    Code:
        [list appendFormat:@", %d", [self nextNumber]];

  10. #10
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    I think I may have tried that last night, but when I do the program locks up on the second button click. Here is the code:

    Code:
    #import <Cocoa/Cocoa.h>
    
    
    @interface control : NSObject {
        IBOutlet id textBox;
    	int a;
    	int b;
    	int c; 
    	int press;
    	int firstPress;
    	NSMutableString *list;
    }
    
    - (IBAction)generate:(id)sender;
    - (int)nextNumber;
    
    @end
    
    
    #import "control.h"
    
    
    @implementation control
    - (IBAction)generate:(id)sender 
    {
    	if (!firstPress)   // print first number in sequence without comma
    	{
    		firstPress = 1;
    		list = [NSMutableString stringWithFormat:@"%d", [self nextNumber]];
    		[textBox setString:list];
    	}
    	else   // print next number in fibonacci sequence with comma before each number
    	{
    		[list appendFormat:@", %d",[self nextNumber]];
    		[textBox setString:list];
    	}
    	
    }
    
    - (int)nextNumber
    {
    	if (!press) // for the first press return 0 because it is the first number in the sequence
    	{
    		press = 1;
    		return 0;
    	}
    	else if (press == 1) // for the second press return 1 because that is the second number in the sequence
    	{
    		press = 2;
    		return 1;
    	}
    	else if (press == 2) // for the third press set a and b equal to the first and second number in the sequence
    	{
    		press = 3;
    		a = 0;
    		b = 1;
    	}
    	else // set a and b as the most recently calculated numbers in the sequence
    	{
    		a = b;
    		b = c;
    	}
    	c = a + b; // determine next value in the sequence by adding the most recent two values
    	return c; 
    }
    
    @end
    The debugger loads all this into the window on the second click. I have never seen it before.

    Code:
    [Session started at 2008-12-18 11:24:27 -0500.]
    
    [Session started at 2008-12-18 11:24:34 -0500.]
    Loading program into debugger…
    GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct  2 04:07:49 UTC 2007)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i386-apple-darwin".Program loaded.
    sharedlibrary apply-load-rules all
    Attaching to program: `/Users/Josh/My Documents/Apps/Fibonacci/build/Debug/Fibonacci.app/Contents/MacOS/Fibonacci', process 1343.
    (gdb)

  11. #11
    Objective - c program help (source included)

    Member Since
    Mar 15, 2007
    Posts
    161
    Specs:
    17" MacBook Pro, 2.33GHz C2D, 2GB RAM
    Quote Originally Posted by JoshMcg View Post
    I think I may have tried that last night, but when I do the program locks up on the second button click.
    First, I'd suggest replacing your declaration of textBox with this:

    Code:
        IBOutlet NSTextField *textBox;
    Also, you're not calling the correct selector on textBox; try setStringValue instead. (The NSTextField declaration above would have allowed the compiler to warn you about using the wrong selector, BTW.)

    Code:
        [textBox setStringValue:list];
    Third, I expect the error you encountered was because you never retained the NSMutableString object returned by stringWithFormat, as the latter returns an autoreleased object in the classic memory management mode (I'm assuming you haven't enabled the garbage collector on this test program). After your first iteration of "generate" completed and program control returned to the runtime loop, the autoreleased string object was automatically deleted. To fix this, you need to at least add the 2nd line below:

    Code:
    list = [NSMutableString stringWithFormat:@"%d", [self nextNumber]];
    
    [list retain];
    It would be safer to instantiate your NSMutableString in the init method (via alloc and init), rather than in one control path of your generate function. Even though that path ought to be the first one that's executed as the code is currently written, it's unwise to rely upon behavioral side effects like that. Using the init method would not only be safer, but would give you a retained string object that wouldn't give you the error you experienced.

    Note that I'm not even touching upon the need to clean up this allocated string object when your program exits. You are getting into a number of areas here, such as Cocoa memory management, for which you need book(s) and a structured approach to learn your way around them; a few posts in a forum aren't going to suffice.

  12. #12
    Objective - c program help (source included)

    Member Since
    Jun 06, 2008
    Posts
    27
    Specs:
    Blackbook - 2.4 GHZ Core 2 Duo - 2 GB RAM - 250 GB HDD
    Thanks again for your help. You were right on with all of your assumptions and the code works perfectly now.

    I am going to the book store right now to read some of Stephen Kochan's first edition objective-c book while I wait for my pre-ordered second edition to come in.

    Just one really quick question though, if I retain list manually like that and never release it is the memory released when the program is closed?

  13. #13
    Objective - c program help (source included)

    Member Since
    Mar 15, 2007
    Posts
    161
    Specs:
    17" MacBook Pro, 2.33GHz C2D, 2GB RAM
    Quote Originally Posted by JoshMcg View Post
    Just one really quick question though, if I retain list manually like that and never release it is the memory released when the program is closed?
    When a program terminates, my understanding is that any allocated memory is normally reclaimed by Mac OS X, whether the memory had been released by the program or not. Memory leaks are primarily an issue while a program is still running. However, it's much smarter to take care of releasing memory and other resources in the program in all cases; failing to do so would be a bit like a Navy fighter pilot who doesn't attempt to catch a wire during a carrier landing, instead trusting to some sort of last ditch*, emergency barricade system to stop his plane from going into the water.

    Caveat: I'm not an expert in Mac OS X's internal behavior in this regard. All I've ever needed to know for my own purposes as an application developer is that it is always best to make certain you're releasing anything you've allocated once you don't need it anymore.

    * is this a pun? I'm not quite sure.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. iOS Devices Now Included In Amazon's Trade-In Program
    By OneMoreThing... in forum Apple Rumors and Reports
    Replies: 0
    Last Post: 05-20-2011, 09:46 AM
  2. Open-source DVD Ripping Program?
    By MoonBoots432 in forum Movies and Video
    Replies: 4
    Last Post: 10-10-2008, 08:37 PM
  3. Can I use the Disk Util program included with Mac to format my External with FAT32
    By darthvader747 in forum Running Windows (or anything else) on your Mac
    Replies: 1
    Last Post: 10-27-2007, 10:19 PM
  4. movie clip making / slideshow program included on Mac?
    By JBPdog in forum Switcher Hangout
    Replies: 2
    Last Post: 07-09-2007, 05:14 PM
  5. Replies: 1
    Last Post: 12-30-2006, 06:18 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •