AppDelegate NSString (Null)
macmaniaque
Membre
Bonsoir,
j'ai créer une classe Raid dans laquelle se trouve un NSString:
Raid.h
@interface Raid : NSObject {
int nbDisk;
NSString *type;
float taille;
}
-(float)calculRaid:(int)nombreDisk:(float)tailleDisk:(NSString *)raidType;
@property (readwrite)int nbDisk;
@property (readwrite, copy) NSString *type;
@property (readwrite) float taille;
J'ai créé une instance dans AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch.
aRaid = [[Raid alloc]init];
return YES;
}
Puis dans 2 autres classe: MainViewController et RaidVisualViewController, je voudrais accéder aux propriétés de cette aRaid qui est créer dans AppDelegate:
RaidAppDelegate *appDelegate = (RaidAppDelegate *)[[UIApplication sharedApplication]delegate];
Lorsque je tente de récupérer et d'afficher les valeurs des propriétées de appDelegate.aRaid toutes fonctionnes sauf pour le type (NString) qui me renvoi (Null):
NSLog(@%f, appDelegate.aRaid.taille); -> 36
NSLog(@Type: %@", appDelegate.aRaid.type); -> Type: (null)
Pouvez-vous m'éclairer, j'ai presque tout tenter pour comprendre (en essayant avec les méthodes value:Forkey: même problème... ?)?
Merci pour votre aide.
j'ai créer une classe Raid dans laquelle se trouve un NSString:
Raid.h
@interface Raid : NSObject {
int nbDisk;
NSString *type;
float taille;
}
-(float)calculRaid:(int)nombreDisk:(float)tailleDisk:(NSString *)raidType;
@property (readwrite)int nbDisk;
@property (readwrite, copy) NSString *type;
@property (readwrite) float taille;
J'ai créé une instance dans AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch.
aRaid = [[Raid alloc]init];
return YES;
}
Puis dans 2 autres classe: MainViewController et RaidVisualViewController, je voudrais accéder aux propriétés de cette aRaid qui est créer dans AppDelegate:
RaidAppDelegate *appDelegate = (RaidAppDelegate *)[[UIApplication sharedApplication]delegate];
Lorsque je tente de récupérer et d'afficher les valeurs des propriétées de appDelegate.aRaid toutes fonctionnes sauf pour le type (NString) qui me renvoi (Null):
NSLog(@%f, appDelegate.aRaid.taille); -> 36
NSLog(@Type: %@", appDelegate.aRaid.type); -> Type: (null)
Pouvez-vous m'éclairer, j'ai presque tout tenter pour comprendre (en essayant avec les méthodes value:Forkey: même problème... ?)?
Merci pour votre aide.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Et sinon, vire la méthode -(float)calculRaid:(int)nombreDisk:(float)tailleDisk:(NSString *)raidType.
Le calcul de la taille doit se faire dans la méthode -[taille].
(taille de type float ?)
#import "Raid.h"
@implementation Raid
@synthesize nbDisk, type, taille;
-(id)init
{
[super init];
self.type=@"";
return self;
}
de la classe Raid ou est déclaré le type (NSString).
Pour ce qui est du reste voici la déclaration des propriétées avec leurs type:
int nbDisk;
NSString *type;
float taille;
@property (readwrite)int nbDisk;
@property (readwrite, copy) NSString *type;
@property (readwrite) float taille;
Enfin, pourquoi virer la méthode calculRaid?
Merci pour vos réponses!
Voici le code:
- (IBAction)calculateRaid:(id)sender
{
appDelegate.aRaid.nbDisk = [nbDiskField.text intValue];
appDelegate.aRaid.taille = [tailleDiskField.text doubleValue];
NSLog(@%i, appDelegate.aRaid.taille);
int index = [raidPickerView selectedRowInComponent:0];
//NSLog(@[allRaidType objectAtIndex:index]: %@", [allRaidType objectAtIndex:index]);
//NSString *leType = (@%@", [allRaidType objectAtIndex:index]);
//appDelegate.aRaid.type = (@%@", leType);
//[appDelegate.aRaid setValue:[allRaidType objectAtIndex:index] forKey:@type];
appDelegate.typeDeRaid = [allRaidType objectAtIndex:index];
NSLog(@%@", [allRaidType objectAtIndex:index]);
NSLog(@%i, appDelegate.aRaid.taille);
//NSLog(@Type: %@", appDelegate.aRaid.type);
resLabel.text = [NSString stringWithFormat:@%.2f Go, [appDelegate.aRaid calculRaid:appDelegate.aRaid.nbDisk :appDelegate.aRaid.taille :[allRaidType objectAtIndex:index]]];
NSLog(@res: %@", resLabel.text);
[resLabel setHidden:NO];
}
Output:
[Session started at 2010-04-26 08:57:55 +0200.]
2010-04-26 08:57:59.636 Raid[394:207] 0
2010-04-26 08:57:59.637 Raid[394:207] 0
2010-04-26 08:57:59.638 Raid[394:207] 0
2010-04-26 08:57:59.638 Raid[394:207] res: 0.00 Go
Déclare plutôt:
[tt]@property (readwrite, retain) NSString *type;[/tt]
Une NSString n'est pas modifiable (contrairement à une NSMutableString), la copier prend juste de la mémoire et du temps.
Parce que ce n'est pas de la programmation objet.
À quoi bon passer tous les paramètres à calculRaid ? L'objet les connaà®t déjà .
Donc, le prototype deviendrait quelque chose comme:
[tt]- (float) calculRaid;[/tt]
Ce qui n'est pas un nom parlant, et qui en pratique te renvoie taille.
Fais le calcul directement dans la méthode - [taille].
taille est un float. Il faut que tu passe %f.
Comment initialises-tu allRaidType ?
Voici comment je déclare allRaidType:
@property (readwrite, retain)NSMutableArray *allRaidType;
@synthetize allRaidType;
- (void)viewDidLoad {
[super viewDidLoad];
allRaidType = [[NSMutableArray alloc]initWithObjects:@"0", @1, @5, nil];
}
Alors voici mon code:
- (IBAction)calculateRaid:(id)sender
{
if(appDelegate==nil)
{
appDelegate = (RaidAppDelegate *)[[UIApplication sharedApplication]delegate];
}
appDelegate.aRaid.nbDisk = [nbDiskField.text intValue];
appDelegate.aRaid.taille = [tailleDiskField.text doubleValue];
NSLog(@Taille 1:%f, [appDelegate.aRaid taille]);
int index = [raidPickerView selectedRowInComponent:0];
//NSLog(@[allRaidType objectAtIndex:index]: %@", [allRaidType objectAtIndex:index]);
//NSString *leType = (@%@", [allRaidType objectAtIndex:index]);
//appDelegate.aRaid.type = (@%@", leType);
//[appDelegate.aRaid setValue:[allRaidType objectAtIndex:index] forKey:@type];
appDelegate.aRaid.type = [allRaidType objectAtIndex:index];
NSLog(@%@", appDelegate.aRaid.type);
NSLog(@taille: %f, appDelegate.aRaid.taille);
//NSLog(@Type: %@", appDelegate.aRaid.type);
resLabel.text = [NSString stringWithFormat:@%.2f Go, [appDelegate.aRaid calculRaid:appDelegate.aRaid.nbDisk :appDelegate.aRaid.taille :appDelegate.aRaid.type]];
NSLog(@res: %@", resLabel.text);
[resLabel setHidden:NO];
}
Explication:
Pour ce qui est "taille est un float. Il faut que tu passe %f." Tu as tout à fait raison, cela à corriger quelque erreurs dans le output.
Enfin, j'avais déclarer appDelegate = (RaidAppDelegate *)[[UIApplication sharedApplication]delegate]; dans la méthode -(id)init que j'avais réécrit pour l'occasion. Du coup je l'ai déplacé à une meilleur place...
Je vais maintenant m'attacher à suivre tes recommandations qui finalement sont complètement vrai ^^
Encore un GRAND MERCI !
En effet, tu ne donnes pas de nom à tes paramètre : le sélecteur (@selector) de ta méthode est "calculRaid:::", et "nombreDisk", "tailleDisk" et "raidType" ne sont que les variables qui vont récupérer les paramètres, mais en Objective-C on donne toujours des noms aux paramètres, devant les ":" qui introduisent lesdits paramètres.
Ainsi, quand tu vas appeler ta méthode, dans ton cas tel que tu l'as déclarée, tu vas l'appeler sous la forme [tt][calculDisk:3 :6 :@toto][/tt] par exemple. Du coup, l'appel à la méthode n'est pas du tout lisible/explicite, on ne comprend pas à quoi correspondent 3, 6 et toto.
Aucune méthode dans le framework Cocoa n'a ce genre de signature : les conventions en Objective-C seraient plutôt d'avoir une méthode que tu pourrais appeler sous la forme [tt][calculRaidWithNombreDisk:3 tailleDisk:6 raidType:@toto][/tt]
Mais quitte à faire plus homogène, autant avoir tout en anglais (parce que là le franglais "NombreDisk"... hum :P), une méthode propre et courte, donc je préconiserai plutôt cette signature : que tu appellerai donc de la manière suivante ensuite :
Sinon, je cherche un moyen pour avoir un object qui peut être lisible dans plusieurs classe. Je pensais que cela était possible avec la classe AppDelegate, mais ce n'est pas le cas, lorsque je réaccède à appDelegate.aRaid, toute les propriétées sont à 0 ou null:
[self.delegate flipsideViewControllerDidFinish:self];
RaidAppDelegate *appDelegate = (RaidAppDelegate *)[[UIApplication sharedApplication]delegate];
NSLog(@Type dans FlipSideView: %f, [appDelegate.aRaid type]);
alors que je voudrais récupérer la valeurs qui a été assigner sur une autre vue de mon Appli, donc dans un autre UIViewController.
Par contre ne pas oublié de faire un release sur ton objet "aRaid".
A vrai dire, j'explore un peu ce coté obscure d'AppDelegate, un point sur lequel je me suis jamais pencher... Et je vois qu'il y a beaucoup de chose à apprendre là -dessus !
Merci pour votre aide!
J'ai dégainé un peu vite. En effet, tu as raison AliGator, le pattern singleton peut-être utilisé à condition qu'une seule instance de cet objet ne puisse exister (comme le App Delegate d'ailleurs qui est construit sur ce schema).
Non, UIApplication est un singleton, mais AppDelegate pourrais être instancié plusieurs fois. En pratique, il n'est instancié qu'une fois, à l'intérieur du XIB, mais ce n'est pas un singleton.
Sinon, pour les objets de l'interface utilisateur, qui ont besoin d'accéder aux outlets, ils sont souvent instanciés dans -[application:didFinishLaunchingWithOptions:], mais pour cet objet Raid, pas besoin, alors mieux vaut le faire dans la méthode -[init]:
oui pour AppDelegate il fallait lire UIApplication
Ce qui m'a embrouillé c'est le faite que pour accéder au AppDelegate j'utilise
MyAppDelegateClass *appDelegate = (MyAppDelegateClass *)[[UIApplication sharedApplication]delegate];
donc j'ai fait le raccourci