iOS Unterklassen eine Benutzerdefinierte Klasse
Ich habe Probleme, packe meine Gedanken über die Vererbung. Ich bin suppsed erstellen einer dashboard-ähnlichen Oberfläche, die in einer app, und habe ich vielleicht 10 widgets/dashlets auf, dass die dashboard-Ansicht. Alle diese dashlets/widgets müssen im Grunde gleich Aussehen, mit einem Titel an der Spitze, Grenzen, Reihe von Tasten auf der Oberseite und ein Diagramm.
Angenommen, ich erstelle eine Unterklasse von UI-View namens "Dashlet' mit Eigenschaften und Steckdosen, und erstellen XIB-Datei mit dem richtigen layout und der angeschlossenen outlets etc.
Will ich jetzt schaffen, mehrere Unterklassen der "Dashlet' Ansicht, dass nur die Daten anders, und zeichnen verschiedene Diagramme. Mein Aktueller code sieht wie folgt aus:
Dashlet.h
@interface Dashlet : UIView{
@private
UILabel *title;
UIView *controls;
UIView *graph;
}
@property (weak, nonatomic) IBOutlet UILabel *title;
@property (weak, nonatomic) IBOutlet UIView *controls;
@property (weak, nonatomic) IBOutlet UIView *graph;
-(Dashlet*)initWithParams:(NSMutableDictionary *)params;
-(void)someDummyMethod;
@end
Und im Dashlet.m
- (id) init {
self = [super init];
//Basic empty init...
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
-(id)initWithParams:(NSMutableDictionary *)params
{
self = [super init];
if (self) {
self = [[[NSBundle mainBundle] loadNibNamed:@"Dashlet" owner:nil options:nil] lastObject];
//some init code
}
return self;
}
Lassen Sie uns jetzt sagen, dass ich erstellen Sie eine Unterklasse namens CustomDashlet.h:
@interface CustomDashlet : Dashlet
@property (nonatomic, strong) NSString* test;
-(void)testMethod;
-(void)someDummyMethod;
@end
und CustomDashlet.m
-(id)init{
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
-(id)initWithParams:(NSMutableDictionary *)parameters
{
self = [super initWithParams:parameters];
if (self) {
//do some stuff
}
return self;
}
Dieser, Art arbeitet, aber ich brauche, um überschreiben von Methoden deklariert, die in der Superklasse oder fügen Sie sogar einige von meinem eigenen. Immer wenn ich versuche etwas zu tun, wie dies in CustomDashlet.m
[self someDummyMethod]
oder sogar [self testMethod]
bekomme ich auch eine exception Fehlermeldung wie diese:
NSInvalidArgumentException', reason: '-[Dashlet testMethod]: unrecognized selector sent to instance
Bin ich noch dabei das richtig? Hab ich was verpasst? Soll ich diese Arbeit machen in irgendeiner anderen Art und Weise? Wenn jemand Vorschläge haben, bitte fühlen Sie sich frei, um Ihre Gedanken zu teilen, ich danke Ihnen für all die Hilfe.
someDummyMethod
und testMethod
?Wo ist die Umsetzung von [self someDummyMethod] und [selbst testMethod] Methoden?
Nicht doppelt, aber deine Frage wird hier beantwortet: stackoverflow.com/questions/19451744/...
Gut, die someDummyMehod ist implementiert in der Oberklasse, und wie es aussieht, obwohl, ich überschreiben in der Unterklasse eine Oberklasse Umsetzung-code aufgerufen wird. Test-Methode ist eine Methode, die ich nicht in der Oberklasse, nur in der Unterklasse, und jedesmal, wenn es aufgerufen wird, bekomme ich die exception, dass kein "testMethod' - Methode in Superklasse.
Die Ausnahme-Methode
-[Dashlet testMethod]: unrecognized selector
zeigt deutlich, dass self
im [self testMethod]
ist ein Dashlet, und nicht ein * CustomDashlet* als Sie erwarten. Sollten Sie noch eine kleine autarke Beispiel demonstriert das problem, insbesondere zeigen, wie das Objekt erstellt wird.InformationsquelleAutor Slavenko Miljic | 2013-11-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist, dass
tut nicht Rückkehr eine
SalesDashlet
Beispiel, wie erwartet, aber einDashlet
Instanz.Hier ist, was passiert:
[SalesDashlet alloc]
ordnet eine Instanz vonSalesDashlet
.initWithParams:
genannt wird, mit dieser Instanz,und fordert
self = [super initWithParams:parameters]
.initWithParams
verwirftself
undüberschreibt es mit einer neuen Instanz geladen, aus der Nib-Datei. Dies ist ein Beispiel
der
Dashlet
.Daher
SalesDashlet *sales
ist "nur" einDashlet
an, und rufen jede UnterklasseMethode, auf löst eine "unbekannte Auswahl" Ausnahme.
Können Sie nicht ändern Sie den Typ der Objekte, die geladen wird in der Nib-Datei. Sie können eine zweite
Nib-Datei mit einem
SalesDashlet
Objekt. Wenn der Hauptzweck der Unterklasse istzum hinzufügen zusätzlicher Methoden, dann ist die einfachste Lösung wäre, diese Methoden
in einem Kategorie der
Dashlet
Klasse.Wie viele Varianten die gleiche Antwort haben, die Sie benötigen, bevor Sie schließlich ausprobiert?
InformationsquelleAutor Martin R
Wenn das problem mit der
Methode ist es, weil die Basisklasse deklariert, mit einem Dashlet Rückgabewert, in der Erwägung, dass die Unterklasse redeclaring es mit einem SalesDashlet Rückkehr Instanz.
Verwenden Sie immer instancetype als Rückgabetyp für alle init-Methode.
id
sollte der Rückgabetyp fürinit
Methoden undinstanceType
sollte der Rückgabetyp fürfactory
Methoden.ist OK für den init-Methoden. Und selbst wenn Sie deklarieren
-(id)initXXX
, die Clang-compiler leise meint-(instancetype)initXXX
.Wie Martin R sagt, der compiler ist unter der Annahme, (instancetype) wenn Sie die id in eine init-Methode ohnehin; so setzen Sie instancetype und explizit sein.
Deklarieren des Rückgabetyps richtig (z.B. als
instancetype
) hilft dem compiler-Fehler zu finden. Aber es ändert nichts an den tatsächlichen Wert zurückgegeben.Ich denke, deine anderen (derzeit gelöschten) Antwort geht in die richtige Richtung.
initWithParams:
in der Unterklasse ruft[super initWithParams:]
, undinitWithParams:
in der OberklasseInformationsquelleAutor Infinity James
Ich glaube, Sie müssen einfach ändern Sie folgende Zeile in Ihre
Dashlet.h
Datei:folgende:
oder besser:
self = [[[NSBundle mainBundle] loadNibNamed:@"Dashlet" owner:nil options:nil] lastObject]
Ist Ihre nib-Datei-Besitzer auf `CustomDashlet' - Klasse? Ohne, dass Sie keinen Zugriff auf die Methoden in dieser Klasse.
InformationsquelleAutor Yas T.
Sie brauchen, um Ihre
init
Methoden.Den Rückgabetyp auf diese beiden sollte
id
.Des Problems, das Sie in Betrieb ist ähnlich zu versuchen, dies zu tun:
Trotz der Deklaration
someArray
alsNSMutableArray
Sie initialisiert haben es alsNSArray
, und als solchesomeArray
tatsächlich eine unveränderlicheNSArray
.So, weil Ihre
SalesDashlet
init-Methode ruft seinesuper
init-Methode und diesuper
ausdrücklich gibt ein Objekt vom TypDashlet
, dann dieSalesDashlet
wird auch wieder ein Objekt vom TypDashlet
, so ist man versucht zu rufentestMethod
(eine Methode, die existiert nur inSalesDashlet
) auf ein Objekt vom TypDashlet
(die nicht wissen, über dietestMethod
- Methode).Änderung Ihrer Rückkehr geben zu
id
machen die Methoden geben ein Objekt des richtigen Typs.Als Hinweis, das Sie getan haben, Ihre
init
, undinitWithFrame
Methoden richtig.Erstellen einer
SalesDashlet
auf diese Weise wird Ihnen erlauben, zu rufen[mySalesDashlet testMethod]
.Ihre
initWithFrame
hat den Rückgabetypid
in super-und Subklassen.Die Ausnahme nicht der Fall, bis er versucht, den Aufruf der Methode auf ein Objekt, das nicht weiß, die Methode. Ich habe laufen in ähnliche Probleme (in einem Kommentar zu der Frage habe ich einen link gepostet auf eine Frage, die ich fragte mich, wo ich war zu sehen, ähnliche Probleme).
Nee, es war ein Witz. Ich weiß einfach nicht, wie Sie 'haha' oder 'lol', um Dinge, die ich sage. Du hast Recht, die extra-detail ist ein netter Zusatz, ich würde irgendwie gerne wissen, von dem Kerl, ob dies die Lösung ist oder nicht, aber da seine Frage war ziemlich unklar.
Moment mal... haben Sie enthalten
SalesDashlet's init methods
imSalesDashlet.h
? Und verändert dieDashlet.h
- header zu korrigieren, diereturn type
für die init-Methode?Ändern die (Erklärung der) Rückgabe-Typ nicht ändern Sie das zurückgegebene Objekt in keiner Weise. - Aber der Ausfall des einen bezeichnet initialisiert (wie in der Frage, die Sie im Zusammenhang mit) könnte ein problem sein.
InformationsquelleAutor nhgrif