Objective-C Mehrere Initialisers
Habe ich eine einfache Frage über das erstellen von mehreren initialisers innerhalb einer objective-c Klasse.
Im Grunde habe ich eine Klasse repräsentiert eine einzelne Zeile in meiner Datenbank (Benutzer). Ich habe zurzeit einen initialiser, die initialisiert die Klasse basiert auf den Benutzer "UserID" (das ist auch der Primärschlüssel in der Datenbank), übergeben wird die user-id der Klasse wird eine Verbindung zu einem webservice analysieren die Ergebnisse und geben ein Objekt initialisiert, um die entsprechende Zeile in der Datenbank.
In dieser Datenbank sind eine Reihe von eindeutigen Feldern (Benutzername und Email-Adresse), möchte ich auch in der Lage sein zu initialisieren, mein Objekt basieren auf diesen Werten. Aber ich bin unsicher, wie mehr als ein initialiser, alles, was ich gelesen habe besagt, dass ich bin frei, mehrere initialisers, solange jeder fordert den designierten initialiser. Wenn mir jemand helfen könnte mit diesem, das wäre toll.
Meine initialiser-code ist wie folgt:
- (id) initWithUserID:(NSInteger) candidate {
self = [super init];
if(self) {
//Load User Data Here
NSString *soapMessage = [NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
"<GetByUserID xmlns=\"http://tempuri.org/\">\n"
"<UserID>%d</UserID>\n"
"</GetByUserID>\n"
"</soap:Body>\n"
"</soap:Envelope>\n", candidate
];
NSLog(@"%@",soapMessage);
//Build Our Request
NSURL *url = [NSURL URLWithString:@"http://photoswapper.mick-walker.co.uk/UsersService.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"http://tempuri.org/GetByUserID" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSError *WSerror;
NSURLResponse *WSresponse;
webData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&WSresponse error:&WSerror];
xmlParser = [[NSXMLParser alloc] initWithData: webData];
[xmlParser setDelegate: self];
[xmlParser setShouldResolveExternalEntities: YES];
[xmlParser parse];
}
return self;
}
Folgenden von Laurent ' s Kommentar habe ich versucht zu implementieren, meine eigene Lösung hat, wäre ich dankbar, wenn Sie könnten, teilen Sie mir das offensichtliche Problem mit dieser Lösung:
Ich bin nicht ganz sicher, ob ich verstehe, du bist die Bedeutung, die ich versucht habe umzusetzen, meine eigene Lösung. Ich wäre Ihnen dankbar, wenn Sie könnten lassen Sie mich wissen, was Sie denken:
- (id) init {
self = [super init];
if(self){
//For simplicity I am going to assume that the 3 possible
//initialation vectors are mutually exclusive.
//i.e if userName is used, then userID and emailAddress
//will always be nil
if(self.userName != nil){
//Initialise object based on username
}
if(self.emailAddress != nil){
//Initialise object based on emailAddress
}
if(self.userID != 0){ //UserID is an NSInteger Type
//Initialise object based on userID
}
}
return self;
}
- (id) initWithUserID:(NSInteger) candidate {
self.userID = candidate;
return [self init];
}
- (id) initWithEmailAddress:(NSString *) candidate {
self.emailAddress = candidate;
return [self init];
}
- (id) initWithUserName:(NSString *) candidate {
self.userName = candidate;
return [self init];
}
Hinsichtlich
- WARNUNG - Anwendung wahrscheinlich Fehler: Sie müssen zu initialisieren, selbst mit den bezeichneten initialiser, BEVOR Sie selbst.Benutzer-id oder ähnliches. Dieses ist, weil 1) die Objekt-Speicher kann zugewiesen werden, um einen neuen Speicherort durch den Aufruf [super init] in [self init], verlieren Ihre initialisierten Variablen und 2) userID kann überschrieben werden durch den Aufruf von [self init]. Tun Sie dies: if (self = [self init]) { self.userID = candidate } return self;
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den designierten Initialisierer definition ist hier. Es ist eine starke Voraussetzung, um sicherzustellen, dass Ihre Instanzen konsistent sind, was die Initialisierung, die Sie verwenden. Für eine vollständige Referenz finden Sie in der Objective-C Programming Guide: die Initialisierung Implementierung ist gut dokumentiert.
Edit 2: Fix typo berichtet von @NSResponder
Edit:
Ich denke Aufruf von init nach Einstellung das Mitglied ist nicht zuverlässig. Die Mitglieder können seltsame Werte, die fehl der test für die Initialisierung.
Einen besseren Weg, es zu tun, ist der Aufruf der "init" - Methode zuerst (die default-Werte für Elemente) und dann das Mitglied. Auf diese Weise haben Sie die gleiche code-Struktur für alle Initialisierungen:
Den Weg, ich Neige dazu, das zu tun diese Art der Sache ist für den designierten Initialisierer werden die Methode nimmt die Parameter und die einfachere Initialisierungen, senden Sie einfach die detaillierte -init-Nachrichten. Zum Beispiel: