Make an NSString global?

Discussion in 'iOS Programming' started by ethana, Aug 2, 2008.

  1. macrumors 6502a

    Joined:
    Jul 17, 2008
    Location:
    Seattle, WA
    #1
    Ok, this is probably a totally newbie question, but how do I make an NSString *moreInfo as a global string that can be changed, used, and obtained via any function?

    I put NSString *moreInfo; above the @implementation block, and one function can use the string, but my touchesEnded:withEvent: function cannot. It pulls the string data back as "invalid".

    Any quick ideas?
     
  2. macrumors member

    Joined:
    Mar 25, 2002
    #2
    You define the NSString *moreInfo in the .h file, not in the .m. You put the definition in the interface section of the .h file, which will make the variable available anywhere in the class.

    You have to allocate memory and instantiate the string once in the .m side of the class. This may be in the init method, or in viewDidLoad or something like that. Without being initiated, the variable will not be valid. You can instantiate moreInfo with something like this:

    moreInfo = @"something";
     
  3. thread starter macrumors 6502a

    Joined:
    Jul 17, 2008
    Location:
    Seattle, WA
    #3
    Still having problems.... again, my touchesEnded:withEvent: function cannot get the string created in viewDidLoad. It pulls the string data back as "invalid". Here's my code after your suggestions:

    AppViewController.h
    Code:
    #import <UIKit/UIKit.h>
    
    @interface FamousBDayViewController : UIViewController {	
    	
    	NSString *moreInfo;
    }
    
    @end
    
    AppViewController.m
    Code:
    #import "AppViewController.h"
    
    @implementation AppViewController
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    	if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    		moreInfo = @"http://www.starturl.com/";
    	}
    	return self;
    }
    
    /*
     Implement loadView if you want to create a view hierarchy programmatically
     - (void)loadView {
     }
     */
    
    - (void)viewDidLoad {
    moreInfo = @"http://www.myurl.com/";
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:moreInfo]];
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    	// Return YES for supported orientations
    	return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    
    - (void)didReceiveMemoryWarning {
    	[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    	// Release anything that's not essential, such as cached data
    }
    
    - (void)dealloc {
    	[super dealloc];
    }
    
    @end
    
     
  4. macrumors regular

    Joined:
    Apr 4, 2007
    #4
    I am not positive, but I think you can do:
    self.moreInfo = @"Testing";

    And to test:
    NSLog(self.moreInfo);
     
  5. macrumors 6502a

    Joined:
    Jul 25, 2001
    #5
    Shouldn't you have to alloc and init the variable?

    Something like this?

    moreInfo = [[NSString alloc] init];
    moreInfo = @"My String Is This";

    Then once no longer need the moreInfo variable (program termination or whenever) you should release the variable.

    [moreInfo release];

    If you don't to the alloc / init then whatever you put into moreInfo is subject to 'cleaning' by the internal memory handling routines... In other words, one second moreInfo could contain/point-to "Testing Testing Testing" and the next second it could become junk that points to nothing..

    Dave
     
  6. macrumors 6502

    Joined:
    Jan 16, 2006
    Location:
    New York, NY
    #6
    You can create some class files.. lets call them global.h and global.m.

    In global.h before the @interface code, define your string with extern.

    extern NSString *myGlobalString;

    In global.m before the @implementation code define a value for the string, or at least give it a blank value

    myGlobalString = @"";

    In any file you need access to this string, add an include "global.h" in the header file and you should be able to use any externs you defined there.
     
  7. macrumors member

    Joined:
    Dec 20, 2008
    #7
    I'm still trying to figure out using a simple string as a global.

    I noticed that in your .h you don't have:

    Code:
    @property (nonatomic, copy) NSString *moreInfo;
    right before @end


    I also use:

    Code:
    self.moreInfo = @"...";


    What I can't figure out is how to READ this information in a different class file. I added the .h at the top of my class file but what is the syntax to read it. To test I am using:

    Code:
    NSLog(self.moreInfo);
    It doesn't like that

    so I tried:

    Code:
    NSLog(myViewController.moreInfo);
    doesn't like that either.
    This should be and probably is quite easy.


    also, don't forget to add under @implementation in your .m file

    Code:
    @synthesize moreInfo;
     
  8. macrumors regular

    xsmasher

    Joined:
    Jul 18, 2008
    #8
    Not quite - objects work differently than simple types like into and float.
    Your first line above creates a string object, and points newInfo at it.
    Your second line creates *another* string, and points moreInfo at it.
    Your first string gets lost (leaked) and you have no way to use it.

    NStrings are immutable - once you create one, you can not "change" it - you can only create a new string and point your variable at it.

    Yes and No. Objects are 'cleaned' (dealloced) my internal routines when they get a release message *which sets their retain count to zero*. Objects have a retain count of one when init'ed, so they're not going to disappear on you.

    Read this to learn more.
    http://www.stepwise.com/Articles/Technical/2001-03-11.01.html

    Re: your global question - make the string a property of your application delegate. It's easy to get the app delegate form any class, and access its properties.
     
  9. macrumors regular

    chameleon

    Joined:
    Mar 4, 2006
    Location:
    Albany, NY
    #9
    I'm sorry to dig up this old thread, but I'm struggling with the same problem as the original poster. In my case I'm using an NSMutableString, but otherwise the problem is essentially the same.

    I define the variable in the .h file like so:

    Code:
    #import <UIKit/UIKit.h>
    
    @interface MyViewController : UIViewController {
    	NSMutableString *gameSolution;
    }
    
    @property (nonatomic, copy) NSMutableString *gameSolution;
    
    @end
    I synthesize it:

    Code:
    @implementation MyViewController
    
    @synthesize gameSolution;
    And then I set the value by reading it from an SQLite database.

    Code:
    gameSolution = [NSMutableString stringWithUTF8String: (char *)sqlite3_column_text(compiledStatement, 0)];
    All pretty simple stuff, and it all works.

    The problem is that when I return to the ViewController after a button click, the value is gone. It's not being retained beyond the scope of the initial pass through the code. Once we leave to let the UI run, the value is lost.

    Can someone please enlighten me as to why? It doesn't make sense to me...

    Thanks!
     
  10. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #10
    Use self.gameSolution to assign it, otherwise you're just assigning the object to the new object but since it's an autoreleased object it's not getting retained thus the deallocation. Using the properties as they're intended results in proper memory management.
     
  11. macrumors regular

    chameleon

    Joined:
    Mar 4, 2006
    Location:
    Albany, NY
    #11
    Bingo! And there it is. It's just that simple.

    I would have never thought of it, so THANK YOU for the help!
     
  12. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #12
    The only reason this didn't work right was because you assigned a value that was autoreleased. If you retained it imediately, it would work just fine and is great if you don't change the value later (where getters/setters really shine).


    To the OP.
    Your code doesn't work because your defined @interface is for a class named "FamousBDayViewController" and your @implementation is for a class named "AppViewController" thus there is no ivar "moreInfo" to set or get...
     

Share This Page