problem with variable wrong assignment

Discussion in 'iOS Programming' started by kikko088, Oct 21, 2010.

  1. kikko088 macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #1
    Hi at all, I have a little problem, I have a function that pass to a var a number, then I pass this var to a method that return this value, at the end I pass this value to another class.
    If I define PassTag with 1,2 or 3 it work perfectly (I see on console the correct value), if I use PassTag = TAG the variable pass 0 instead 1,2 or 3.
    A strange thing is that in varID put an NSLog that was print 2 times (instead 1) and the first stamp is correct while the second print is 0.
    Any tips?


    Code:
    	
    ListView.h
    //Variabili
    	int TAG;
    	int PassTag;
    	
    }
    
    - (void) listener:(id) sender;
    - (int) varID;
    
    Code:
    ListView.m
    - (void) listener:(id) sender
    {
    .....
     	TAG = [[co id] intValue];
    	[self varID];
    ....
    	[detailArg release];
    }
    
    - (int) varID
    {
    	// PassTag = 1;   WORK
    	PassTag = TAG;  // NOT WORK
    	NSLog(@"Tag = %d",PassTag);	
    	return PassTag;
    }
    Code:
    	
    controller2.m
    ListView *my_ID = [[ListView alloc] init];
    variabileID = [my_ID varID];
    	
    NSLog(@"VariabileID da lettura database = %d",variabileID);
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    You've shown us the code for controller (.h and .m) but not ListView.
     
  3. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
  4. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #4
    So, in this line:
    Code:
    variabileID = [my_ID varID];
    you are expecting variabileID to contain the value of TAG ?
     
  5. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #5
    yes, I want to put the TAG value on variabileID.
    Need to put on the thread other code?
     
  6. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    Well, in this code:
    Code:
    ListView *my_ID = [[ListView alloc] init];
    variabileID = [my_ID varID];
    you instantiate my_ID and then immediately call varID, so at no point have you given the listener: action method an opportunity to be called. Therefore, TAG's value is never set.
     
  7. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #7
    Thank you, but perhaps I don't understand, I write the rest of the code, because the "listener:" need to pass the id from button to the next method.
    If I put a NSLog in this point
    Code:
    	
    TAG = [[co id] intValue];
    [self varID];
    NSLog(@"Listener PassTag = %d",PassTag);  // HERE THE TAG IS CORRECT //
    
    I get the correct tag, than I think that the tag was set (I think that because I read on the console the correct tag) or despite this it isn't set? (I want to understand if my reasoning is correct)

    Code:
    #import "ListView.h"
    #import "ContenutoObject.h"
    #import "DataMaterie.h"
    
    
    @implementation ListView
    @synthesize detailArg;
    
    - (void)viewDidLoad
    {
    	[VistaScroll setScrollEnabled:YES];
    	[VistaScroll setContentSize:CGSizeMake(320,600)];
    	[super viewDidLoad];
    	[self createButtons];
    }
    
    
    - (void) createButtons
    {
    #define TAG_INDEX 1000
    #define BUTTON_HEIGHT 100.0
    #define X_GAP 40.0
    #define Y_GAP 30.0
    
    
    	DataMaterie *data = [[DataMaterie alloc] init];
    	[data path];
    
    	
    	
    	int count = 0;
    	double y = Y_GAP;
    
    	for ( ContenutoObject *co in data.array_contenuti )
      {
    	double x = X_GAP + ( BUTTON_HEIGHT * ( count % 2 ) );
        if ( count && ( count % 2 ) == 0 ) y += BUTTON_HEIGHT + Y_GAP;
        if ( count % 2 ) x += X_GAP;
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.frame = CGRectMake( x, y, BUTTON_HEIGHT, BUTTON_HEIGHT );
        [button setTitle:co.Materia forState:UIControlStateNormal];
        [button addTarget:self action:@selector( listener: ) forControlEvents:UIControlEventTouchUpInside];
    	button.tag = TAG_INDEX + count;
        [self.view addSubview:button];
        ++count;
    	  
    
      }
    
    	NSLog(@"Loop bottoni Materie OK");
    }
    
    
    
    - (void) listener:(id) sender
    {
      int index = [sender tag] - TAG_INDEX;
    
    	DataMaterie *data = [[DataMaterie alloc] init];	
    	[data path];
    	ContenutoObject *co = [data.array_contenuti objectAtIndex:index];
    
    	TAG = [[co id] intValue];
    	[self varID];
    	NSLog(@"Listener PassTag = %d",PassTag);  // HERE THE TAG IS CORRECT //
    
    
    
    
    	// Push view controller as appropriate
    	detailArg = [[ArgomentiController alloc] initWithNibName:@"ListaArgomento" bundle:[NSBundle mainBundle]];
    	[self.navigationController pushViewController:detailArg animated:YES];
    
    	// Set the title of the view to the argoment
    	self.detailArg.title = [co Materia];
    
    
    	[detailArg release];
    
    }
    
    - (int) varID
    {
    	PassTag = 1;
    	NSLog(@"PassTag = %d",PassTag);
    	return PassTag;
    
    }
    
    
    - (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
        
        // Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    
    - (void)dealloc {
        [super dealloc];
    }
    
    @end
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    Where, specifically, does this code reside?:
    Code:
    ListView *my_ID = [[ListView alloc] init];
    variabileID = [my_ID varID];
    	
    NSLog(@"VariabileID da lettura database = %d",variabileID);
     
  9. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #9
    on this file, DataArgomenti is for take some data from database

    Code:
    #import "DataArgomenti.h"
    #import "iIngAppDelegate.h"
    #import "ContenutoObjectArgomento.h"
    #import "ArgomentiController.h"
    #import "ListView.h"
    
    @implementation DataArgomenti
    @synthesize arrayArgomenti;
    
    -(void) path {
    	
    	// Override point for customization after application launch.
    	// Setup some globals
    	databaseName = @"ARGOMENTI.sqlite";
    	
    	// Get the path to the documents directory and append the databaseName
    	NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    	NSString *documentsDir = [documentPaths objectAtIndex:0];
    	databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
    	
    	// Execute the "checkAndCreateDatabase" function
    	[self checkAndCreateDatabase];
    	// Execute the "readArgFromDatabaseMaterie" function
    	[self readArgFromDatabaseArgomenti];	
    	
    }
    
    -(void) checkAndCreateDatabase {
    	// Check if the SQL database has already been saved to the users phone, if not then copy it over
    	BOOL success;
    	
    	// Create a FileManager object, we will use this to check the status
    	// of the database and to copy it over if required
    	NSFileManager *fileManager = [NSFileManager defaultManager];
    	
    	// Check if the database has already been created in the users filesystem
    	success = [fileManager fileExistsAtPath:databasePath];
    	
    	// If the database already exists then return without doing anything
    	if(success) return;
    	
    	// If not then proceed to copy the database from the application to the users filesystem
    	
    	// Get the path to the database in the application package
    	NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
    	
    	// Copy the database from the package to the users filesystem
    	[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
    	
    	[fileManager release];
    }
    
    
    
    -(void) readArgFromDatabaseArgomenti {
    
    	ListView *my_ID = [[ListView alloc] init];
    	variabileID = [my_ID varID];
    	
    	NSLog(@"VariabileID da lettura database = %d",variabileID);
    	
    	
    	// Setup the database object
    	sqlite3 *database;
    	// Init the argoments Array
    	arrayArgomenti = [[NSMutableArray alloc] init];
    	
    	// Open the database from the users filessytem
    	if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    		// Setup the SQL Statement and compile it for faster access
    		const char *sqlStatement = [[NSString stringWithFormat:@"select * from ARGOMENTO WHERE id_materia='%d'",variabileID] UTF8String];
    		// const char *sqlStatement = "select * from ARGOMENTO";
    		sqlite3_stmt *compiledStatement;
    		if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
    			// Loop through the results and add them to the feeds array
    			while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
    				// Read the data from the result row
    				NSString *aID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
    				NSString *aIDMateria = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
    				NSString *aDescArgomento = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
    				
    				// Create a new argoments object with the data from the database
    				ContenutoObjectArgomento *contenutoArgomento = [[ContenutoObjectArgomento alloc] initWithName:aID idMateria:aIDMateria descArgmento:aDescArgomento];
    				[arrayArgomenti addObject:contenutoArgomento];
    				
    				[contenutoArgomento release];
    			}
    		}
    		
    		
    		// Release the compiled statement from memory
    		sqlite3_finalize(compiledStatement);
    		
    	}
    	sqlite3_close(database);
    	
    }
    
    
    - (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
        
        // Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    
    - (void)dealloc {
    	[arrayArgomenti release];
        [super dealloc];
    }
    
    
    @end
    
     
  10. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    So, the problem is you're creating a new ListView instance rather than referencing the existing instance. (Seems to be a theme today. :) )
     
  11. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
  12. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #12
    How do you normally solve programming problems?
     
  13. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #13
    looking around the forum for the answer of similar problem and trying alone some code, reading some guides, now I discovered NSLog for see some result on console but this problem is (for me) a logical problem, I don't understand where is the other listview instance and especially i don't understan why with a simple number the program work while with the variable not work. :( :D




    kikko088
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #14
    I think this may be a case where you cannot completely rely on another solution to help you. You may have to draw inspiration from a similar issue but then you'll have to apply your own creativity and ingenuity to come up with a solution for your unique situation.

    Well, at one point in your code, when you instantiate an ArgomentiController and push it onto the navigation stack, you are executing from within a instance of ListView, right?

    It's all a matter of code execution flow. When you hardcode your value (set it to a simple number), you are doing that right before you need a value set. When you set the value to the variable, the code that is responsible for setting that value has not yet been executed; therefore, it contains nothing.
     
  15. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #15
    Ok now I understand but is an instance in ListView, while (from what I've understand) for passing the value to another controller I have to create an object of ListView and use it for pass the value (perhaps I'm confused :D) with my method.

    ok understand but Image if you see the image the value is stored correctly, but at the end it is cleared.
    ps. there is only one NSLog, alse if there is two print of PassTag
     
  16. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #16
    You don't need to create an object if you already can have a reference to an existing instance.

    For example, if you look at the Metronome sample app, you will see that MetronomeView contains a metronomeViewController property that is set in MetronomeViewController's loadView. Then, in MetronomeView, that can be referenced like any other instance variable, such as in the showInfo method.

    It is not "cleared"; you are simply referencing the value from two different instances: one where it's set correctly and one where it hasn't because you created a new instance and thus the value is only set to the "default".
     
  17. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #17
    ufff so difficult :( :confused:
    I read and reread the code but I don't understand how can I solve on my app...in my DataArgomenti there isn't a ListView instance...
    Looking on the metronome app I see that the method was calling with [controller method] than I try on my app to put

    [ListView varID]

    but I recive a ListView may not respond to '+varID'



    kikko088
     
  18. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #18
    Not unless you put one there. :)

    controller is an instance variable; ListView is not: it's a class name.

    If you are struggling with the difference between an instance method and a class method, I think it's time to step back from the real coding and go (re)learn the basics of Objective-C programming.
     
  19. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #19
    It's time to START learn Object-C :) :eek:

    from what I have understand instance method is refer to an object of the class while and a class method is refer to class

    Can you show me the correct code?
     
  20. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #20
    Yes, please!

    Sorry but that's not how I operate. I don't just give solutions, especially when you don't understand the fundamentals or I'm not being paid (which we can't discuss on these forums). Because all I'm doing then is providing code you can copy-and-paste but probably don't understand.
     
  21. kikko088 thread starter macrumors member

    Joined:
    Oct 13, 2010
    Location:
    Italy
    #21
    But perhaps could help me to understand, however no problem, :) has already done too :D thank you.
    Last question,

    Code:
    dataArg.h
    ListView *ListController;
    dataArg.m
    variabileID = [ListController varID];
    NSLog(@"VariabileID da lettura database = %d",variabileID);
    
    is the correct way?
     
  22. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #22
    First, the common convention is class names begin with an uppercase letter (such as "Rectangle"); the names of instances typically begin with a lowercase letter (such as "myRect").

    Second, once you think you've learned Objective-C, revisit your code from above and try to decide for yourself if it's the correct way.
     

Share This Page