ViewController: Instanzvariable gesucht

frauenPower

Aktives Mitglied
Thread Starter
Dabei seit
21.06.2011
Beiträge
287
Reaktionspunkte
75
Guten Abend,

nachdem meine Bücher dann doch nicht gekommen sind, bin ich dabei mich in die ViewController-Geschichte einzuarbeiten und habe mir ein View-Based-Project namens Vcexample angelegt.

Laut Beschreibung meines DVD-Kurses, und eben auch meiner bis dato gemachten Erfahrungen, fehlt mir etwas im Headerfile meiner Delegate-Klasse:

Code:
@class VcexampleViewController;

@interface VcexampleAppDelegate : NSObject <UIApplicationDelegate> {

}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet VcexampleViewController *viewController;

Wie kann ich für etwas eine property erstellen, "IBOutlet...viewController" wenn ich vorher die Instanzvariable mit "VcexampleViewController *viewController" nicht angelegt habe.

:rolleyes:

Im Buch- als auch im DVD-Beispiel sind die jeweils von Xcode angelegt worden. Bei mir nicht.
Natürlich auch in der Implementierung der entsprechende "synthesize". Setter- und Gettermethoden für etwas, was ich gar nicht deklariert habe :confused:

Habt Ihr eine Erklärung dafür. Erklären kann es mir die Literatur nicht, denn da steht die Deklaration ja.

Liebe Grüße
Karin
 
Aha, dies kann ich quasi in der Implementierung mit:
@synthesize viewController=_viewController;
nachholen. Jetzt wird wohl das property durch die Instanzvariable "_viewController" repräsentiert.

Richtig?

Liebe Grüße
Karin
 
Aaaaaaaber die Unterschiede gehen weiter.

Wollen doch mal schauen, wie das View nun von Xcode geladen wird und wie es Karin lädt:
Code:
    //Dass hat Xcode angelegt = funktioniert natürlich
    self.window.rootViewController = self.viewController;
    
    //Das hat Karin angelegt = funktioniert natürlich auch
    [self.window addSubview:_viewController.view];

Geht beides.

Nur der Xcode-Code ist mir nicht verständlich. Mal bei Apple nachsehen, warum das jetzt so gemacht wird und warum denn dann überhaupt "_viewController" instanziiert wurde, wenn es nicht verwendet wird. Zumindest für mich nicht ersichtlich.

Liebe Grüße
Karin
 
Für eventuelle Mitleser: Der Xcode-Code wurde mit iOS 4.0 eingeführt. Demnach wäre eine Applikation, die damit erstellt werden würde, unter 3.2 nicht lauffähig.

Ich persönlich finde die "alte" (für mich dann weiter neue) Art verständlicher. Frage mich immer noch, wo sich "_viewController" versteckt. Eine Variable ohne Funktion kann es ja nicht geben. Nutzlose Objekte gehören in den Trash.


Liebe Grüße
Karin
 
Hat niemand eine hilfreiche Idee für mich?

Finde die Erklärung für die Codezeile nicht, die Xcode da angelegt hat. Gibt es von Apple eine Art Dokumentation der Änderungen zu vorangegangen iOS-Versionen und dort vielleicht auch eine Erklärung für den Code?

Den "alten" Code halte ich für verständlich, der neue :rolleyes:

Lieben Gruß
Karin
 
Guten Morgen,

schade, dann lass ich den Code von Xcode einfach mal so stehen und hoffe, die Vorgehensweise später verstehen zu können.

Liebe Grüße
Karin
 
Viele Frameworks die solche Layoutdateien benutzen erstellen automatisch neue
Instanzen der Klassen die für das Layout gebraucht werden. In den meisten Fällen
werden die Instanzen als Subviews einer SuperView gespeichert, wodurch ein Baum
von Views entsteht. Die Wurzel dieses Baumes ist deine RootView welche in der
Regel nicht verändert werden sollte. In manchen Fällen ist es sogar explizit von Apple
verboten bestimmte Views nicht als RootView zu verwenden.
 
Hallo Karin

Ich unternehme mal den Versuch einer Antwort. Nehmen wir mal folgende Klassendeklaration:
Code:
@interface MyViewController : NSObject
{
    // Das ist eine Instanzvariable. IBOutlet ist nur eine Markierung für Xcode.
    IBOutlet NSView *_myView;
}

// Diese @property Zeile sagt, dass folgende Methoden existieren müssen:

//  - (NSView *)myView;
//  - (void)setMyView:(NSView *)aView;

@property (retain) NSView *)myView;

@end

Code:
@implementation MyViewController

// Folgendes Zeile implementiert für Dich anhand der @property Deklaration
// die Methoden von oben:

@synthesize myView = _myView;

// Du kannst die aber auch selbst implementieren, dass ist (fast) dasselbe:

- (NSView *)myView
{
    return myView;
}

- (void)setMyView:(NSView *)aView
{
    // Falls myView == aView ist, muss man erst "retain" aufrufen,
    // sonst würde myView (aView) zu früh freigegeben.

    [aView retain];
    [myView release];
    myView = aView;
}

@end

Du brauchst den Unterstrich vor der Instanzvariable eigentlich nicht, Du kannst
nämlich eine "Property" in eine andere Instanzvariable speichern.

Zum Beispiel so, mit einem NSDictionary:

Code:
@interface MyViewController : NSObject
{
    // Hier benutzen wir sinnloser Weise ein Dictionary als Speicherplatz.
    // Fuer viele Views ;)
    NSMutableDictionary *allMyViews;
}

// Diese @property Zeile sagt, dass folgende Methoden existieren müssen:

//  - (NSView *)myFirstView;
//  - (void)setMyFirstView:(NSView *)aView;

// Man kann IBOutlet auch in die @property schreiben.
// Hier muss man es sogar, weil es am NSDictionary keinen Sinn macht.

@property (retain) IBOutlet NSView *)myFirstView;

// Diese @property Zeile sagt, dass folgende Methoden existieren müssen:

//  - (NSView *)mySecondView;
//  - (void)setMySecondView:(NSView *)aView;

@property (retain) IBOutlet NSView *)mySecondView;

@end

Code:
@implementation MyViewController

// Da Du jetzt nicht @synthesize benutzen kannst, da die NSViews in ein
// Dictionary abgelegt werden, musst Du die @properties selbst implementieren.

- (NSView *)myFirstView
{
    return [allMyViews objectForKey@"firstView"];
}

- (void)setMyFirstView:(NSView *)aView
{
    [allMyViews setObject:aView forKey:@"firstView"];
}

- (NSView *)mySecondView
{
    return [allMyViews objectForKey@"secondView"];
}

- (void)setMySecondView:(NSView *)aView
{
    [allMyViews setObject:aView forKey:@"secondView"];
}

@end

Was ich damit sagen will ist, dass @properties nur deklarieren was an Methoden existieren soll.

Falls Du Instanzvariablen gleichen Typs im Interface deklarierst, kann der Compiler mit der @synthesize Direktive diese Methoden für Dich implementieren.

Du kannst aber auch ganz andere Speichermethoden für properties implementieren.

Es ist nur einfacher, mit @property und @synthesize zu arbeiten, aber der Effekt ist derselbe.

Natürlich ist das NSDictionary nicht sinnvoll, aber zur Erklärung passt es. Du kannst Dir ganz andere Szenarien ausdenken, in denen der ViewController properties bereitstellt, die ganz woanders abgelegt werden.

Ich habe übrigens "-(id)init" weggelassen, Du musst das NSDictionary auch erzeugen. Ausserdem fehlt "- (void)dealloc".

Gruss

PS: Alles getippt, nichts compiliert.
 
@pmau

Lieben, lieben Dank.
Habe ich mir ausgedruckt und werde es mal durcharbeiten. Man, hast Du Dir Mühe gemacht.

Der Code kann ruhig den einen oder anderen Fehler haben, um den geht es mir nicht primär. Ich will die Sache verstehen und da denke ich, komme ich mit Deiner Hilfe schon eine ganze Ecke weiter.

@yunharia
Ebenfalls dickes Dankeschön, ist mit ausgedruckt worden und gleich morgen gehe ich dann an die gesammelten Werke.

Liebe Grüße
Karin

Habe heute programmatisch meine ersten Viewcontroller erstellt und auch die ersten Objekte, natürlich programmatisch, auch darauf platziert. Experimentiere da den ganzen Tag schon und mich hat halt interessiert, wie ich den Code, der von Xcode angelegt wurde, zu verstehen habe.
 
Zurück
Oben Unten