Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ethana

macrumors 6502a
Original poster
Jul 17, 2008
836
0
Seattle, WA
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?
 

gralem

macrumors member
Mar 25, 2002
48
0
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";
 

ethana

macrumors 6502a
Original poster
Jul 17, 2008
836
0
Seattle, WA
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
 

Garrett

macrumors regular
Apr 4, 2007
173
0
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

I am not positive, but I think you can do:
self.moreInfo = @"Testing";

And to test:
NSLog(self.moreInfo);
 

DaveGee

macrumors 6502a
Jul 25, 2001
677
2
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
 

johnnybluejeans

macrumors 6502
Jan 16, 2006
294
0
New York, NY
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.
 

mcannell

macrumors member
Dec 20, 2008
36
0
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;
 

xsmasher

macrumors regular
Jul 18, 2008
140
0
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.

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.

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..

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.
 

chameleon

macrumors regular
Mar 4, 2006
123
0
Albany, NY
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!
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
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.
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
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!
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...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.