Anfängerfrage: globale Variablen

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
Hallo,

folgendes Problem und Sourcecode (gekürzt).

Ich habe die AppDelegate.h, dort steht:

@interface AppDelegate : NSObject >UIApplicationDelegate>
{
NSString *benutzerID;
}

@property (nonatomic, retain) NSString *benutzerID;

in der AppDelegate.m:
[...]
@synthesize benutzerID;

In dieser AppDelegate lese ich auch mein SettingsBundle aus, die Zuweisung erfolgt mit:
[...]
benutzerID = [[NSUserDefaults standardUserDefaults] stringForKey:BenutzerIDSetting];

Lasse ich mir das mit
NSLog(@"benutzerID: %@", benutzerID);
dann funktioniert das einwandfei.

In meiner DataSheetTableView möchte ich jetzt als Überschrift diese BenutzerID haben, was muss ich jetzt im DataSheetTableViewController schreiben?

self.navigationItem.title= @"ID: %@", ???;

Egal was ich aufrufe, ich bekomme immer die Fehlermeldung error: ‘benutzerID‘ undeclared

Da ich in diesem Controller oben #import "AppDelegate.h" stehen habe, müsste diese Variable doch bekannt sein?

Danke
iQuaser
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
OK - hat sich erledigt. Ich rufe die Settings-Einstellung einfach in dem ViewController mit

tempBenutzerID = [[NSUserDefaults standardUserDefaults] stringForKey:@"userIDKey"];

ab.

NSLog gibt dies auch brav aus.

Problem: self.navigationItem.title = tempBenutzerID; gibt nur ein leeres Fenster aus.

Kann es sein, dass man in die Überschrift einer Tabelle keine Variablen, sondern nur Strings wie @"Blubber" übergeben kann?
 

torbenH

Neues Mitglied
Registriert
28.01.2006
Beiträge
21
Moin moin,

aus meiner Sicht ist der zur Verfügung gestellte Quelltext-Ausschnitt zu kurz, um das Problem zu erkennen. Bin im Bereich Obj-C und Cocoa kein Profi, bin aber durchaus im zweiten Jahrzehnt meiner Programmiererfahrung. ;-)

Davon abgesehen ist die Fehlermeldung deines ersten Beitrags oben logisch. benutzerID ist eine Variable der Klasse AppDelegate, daher kannst du sie aus deinem DataSheetTableViewController auch nicht direkt lesen. Es ist eben keine globale Variable.
Zum Thema "@-String" oder NSString als Überschrift: Das was du vermutest kann nicht das Problem sein, da @"" nur ein Makro ist, das im Endeffekt auch nur eine NSString-Instanz erzeugt. Versuch es mal mit
Code:
NSString stringWithFormat:(NSString *)format
Sollte das nicht helfen, liegt der Fehler woanders, vermutlich muss die Überschrift einfach anders gesetzt werden.
Wie gesagt, es gibt hier garantiert genug andere, die sich besser mit Cocoa auskennen...
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
Dann mal ein blöde Frage:

Wie erzeuge ich eine globale Variable?

Ich dachte, es reicht, wenn ich die Klasse, in der ich die Variable erzeugt habe, importiere....
 

_ebm_

Aktives Mitglied
Registriert
19.01.2008
Beiträge
2.079
Wozu willst du denn bitte eine globale Variable erzeugen? In objektorientierten Sprachen kannst du öffentliche Klassenvariablen nutzen. Globale Variablen "gibt es nicht".
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
Wozu willst du denn bitte eine globale Variable erzeugen? In objektorientierten Sprachen kannst du öffentliche Klassenvariablen nutzen. Globale Variablen "gibt es nicht".

Das Problem ist, dass ich die BenutzerID, die ich in der AppDelegate aus den Settings auslese, in meinem TableViewController benötige - aber leider keinen Zugriff darauf habe (selbst wenn ich sie als public anlege).

Das ist das seltsame, an dem ich gerade tüftle
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
Habe den Fehler gefunden... war ein simpler Tippfehler *fluch*

Trotzdem: Danke für die Hilfe und die Tipps :upten:
 

nonsense

Aktives Mitglied
Registriert
29.10.2004
Beiträge
1.394
...ohne jetzt alles gelesen zu haben.

Du hast die Property ja im App-Delegate erstellt, entsprechend kannst Du sie aufrufen.

In der Klasse, wo Du auf die Eigenschaft zugreifen willst, importierst Du Deine App-Delegate-Klasse via
Code:
#import "???.h"
, dann erstellst Du eine App-Delegate-Instanz:

Code:
???* appDelegate = [[UIApplication sharedApplication] delegate];

die ??? musst Du mit dem Klassennamen Deiner App-Delegate ersetzen. Jetzt kannst Du einfach via appDelegate.benutzerID auf deine Eigenschaft zugreifen.

Gruss
 
Zuletzt bearbeitet:

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
@nonsense:

Das hatte ich auch schon versucht, aber irgendwie hat er mir beim Laden die Variable nicht gezogen, der Wert war immer null.

Habe es jetzt so gelöst (in der "-(id) initWithTabBar"):


Code:
// Auslesen des Wertes aus dem Settings.bundle (ist dort als "userIDKey" angelegt
NSString *temp = [[NSUserDefaults standardUserDefaults] stringForKey:@"userIDKey"];

// den Text "eigene ID" vor dem Variablenwert anhängen
NSString *navigationItemTitle = [@"eigene ID: " stringByAppendingString:temp];

// und die Ausgabe
self.navigationItem.title= navigationItemTitle;

Sieht dann so aus:
 

nonsense

Aktives Mitglied
Registriert
29.10.2004
Beiträge
1.394
...ich denke, dann musst du irgend etwas falsch gemacht haben. ich musste schon etliche male objekte an mehrere controller weiterreichen, was ich eigentlich ganz gerne über diesen weg mache. klappt denn jetzt alles?

gruss
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
...ich denke, dann musst du irgend etwas falsch gemacht haben. ich musste schon etliche male objekte an mehrere controller weiterreichen, was ich eigentlich ganz gerne über diesen weg mache. klappt denn jetzt alles?

gruss

So wie von mir oben beschrieben klappt es wunderbar :)

Mit der appDelegate findet er beim Initialisieren der View (initWith....) die Werte (noch?) nicht.

Geht ja auch nur um die Anzeige der ID - meine Werte aus dem Objekt kommen aus einer anderen Klasse, die findet er einwandfrei. Jetzt muss ich nur noch in der Doku stöbern, wie ich die Überschrift als Button umwandeln kann ;) (siehe Bild) - wenn ich da draufdrücke will ich, dass auf die Kartenansicht gewechselt wird und die Karte sich auf meine Position zentriert *stöhn*

Alles recht strange auf diesem iPhone :o

attachment.php
 

Anhänge

  • Bild 2.png
    Bild 2.png
    12,6 KB · Aufrufe: 138

nonsense

Aktives Mitglied
Registriert
29.10.2004
Beiträge
1.394
...mach Dir ein UITouch, werte die Koordinaten via locationInView aus. Das ganze packst Du in die touchesEnded:withEvent: Deines View-Controllers. Wenn der CGPoint der locationInView innerhalb des entsprechenden Bereichs liegt, führst Du die Methode für Deine map aus.

Gruss
 

nonsense

Aktives Mitglied
Registriert
29.10.2004
Beiträge
1.394
...zwecks dem appDelegate-Problem: Nutze mal die viewDidLoad statt initWithNIB. Ich denke, das war Dein Problem.

Gruss und gute Nacht.
 

nonsense

Aktives Mitglied
Registriert
29.10.2004
Beiträge
1.394
...poste doch mal deine .m deiner view-controller klasse zumindest die viewDidLoad.

gruss
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
DataSheetViewController.h

Code:
#import <UIKit/UIKit.h>


@interface DataSheetViewController : UITableViewController 
{
	UIToolbar	*toolbar;

}

@property (nonatomic, retain) UIToolbar *toolbar;


- (id)initWithTabBar;

@end

DataSheetViewController.m
Code:
-(id) initWithTabBar 
{
	if ([self init]) 
	{
		//this is the label on the tab button itself
		self.title = @"Tabellenansicht";
		//use whatever image you want and add it to your project
		self.tabBarItem.image = [UIImage imageNamed:@"DataSheetIcon.png"];
		
		// set the long name shown in the navigation bar		
		NSString *temp = [[NSUserDefaults standardUserDefaults] stringForKey:@"userIDKey"];
		NSString *navigationItemTitle = [@"eigene ID: " stringByAppendingString:temp];
		self.navigationItem.title= navigationItemTitle;
		
		self.tableView.delegate = self;
		self.tableView.dataSource = self;
		self.tableView.rowHeight = 48;
		self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
		self.tableView.sectionHeaderHeight = 0;
	}
	return self;
	
}


- (void)viewDidLoad 
{
    [super viewDidLoad];
	

	
	UIBarButtonItem *addButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
    self.navigationItem.rightBarButtonItem = addButtonItem;
    [addButtonItem release];
	
		
	
	
}

So funktioniert es :)
 

iQuaser

Mitglied
Thread Starter
Registriert
25.07.2008
Beiträge
884
Zusatz: Die Tab Bar wird in der <Name>AppDelegate so angelegt:

Code:
- (void)applicationDidFinishLaunching:(UIApplication *)application 
{    
	
#pragma mark TabBar, NavigationController
	// set up a local nav controller which we will reuse for each view controller
	UINavigationController *localNavigationController;
	
	// set up the window
	//[window setBackgroundColor:[UIColor blackColor]];
	
	// create tab bar controller and array to hold the view controllers
	tabBarController = [[UITabBarController alloc] init];
	NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:3];
	
	// setup the first view controller (Root view controller)
	RootViewController *myViewController;
	myViewController = [[RootViewController alloc] initWithTabBar];
	
	// create the nav controller and add the root view controller as its first view
	localNavigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
	
	// add the new nav controller (with the root view controller inside it)
	// to the array of controllers
	[localControllersArray addObject:localNavigationController];
	
	// release since we are done with this for now
	[localNavigationController release];
	[myViewController release];
	
	// setup the second view controller just like the first
	DataSheetViewController *dataSheetViewController;
	dataSheetViewController = [[DataSheetViewController alloc] initWithTabBar];
	localNavigationController = [[UINavigationController alloc] initWithRootViewController:dataSheetViewController];
	[localControllersArray addObject:localNavigationController];
	[localNavigationController release];
	[dataSheetViewController release];
	
	// setup the third view controller just like the first
	MapViewController *mapViewController;
	mapViewController = [[MapViewController alloc] initWithTabBar];
	localNavigationController = [[UINavigationController alloc] initWithRootViewController:mapViewController];
	[localControllersArray addObject:localNavigationController];
	[localNavigationController release];
	[mapViewController release];
	
	
	// load up our tab bar controller with the view controllers
	tabBarController.viewControllers = localControllersArray;
	
	// release the array because the tab bar controller now has it
	[localControllersArray release];
	
	// add the tabBarController as a subview in the window
	[window addSubview:tabBarController.view];
	
    // need this last line to display the window (and tab bar controller)
    [window makeKeyAndVisible];
 

nonsense

Aktives Mitglied
Registriert
29.10.2004
Beiträge
1.394
wie schon geschrieben: einfach die appDelegate importieren (#import"..."), dann in deiner viewDidLoad:

Code:
KlasseAppDelegate* appDelegate = [[UIApplication sharedApplication] delegate]

jetzt kannst Du auf die Eigenschaften der AppDelegate z.B. via Dot-Notation zugreifen.

Gruss
 
Oben Unten