2015-05-14 15 views
11

Ich möchte eine Klasse erstellen, die von zwei benutzerdefinierten Klassen erben kann. Haben Sie eine Idee, dies bitte zu tun? Bitte siehe unten mein Beispiel:Multi-Vererbung für IOS

erste Klasse:

@interface UIZoomableView : UIView 
{ 
    UITapGestureRecognizer *_tapGestureRecognizer; 
} 

und Umsetzung:

- (void)onDoubleTap:(UITapGestureRecognizer *)sender 
{ 
    CGSize newSize; 
    CGPoint centerPoint = self.center; 
    if ([self isSmall]) 
    { 
     newSize = [self bigSize]; 
    } 
    else 
    { 
     newSize = [self smallSize]; 
    } 

    [UIView animateWithDuration:0.3 animations:^{ 
     self.size = newSize; 
     self.center = centerPoint; 
    }]; 
} 

Zweite Klasse:

@interface UIDraggableView : UIView 

    UIPanGestureRecognizer *_panGestureRecognizer; 

@end 

Umsetzung:

- (void)handlePan:(UIPanGestureRecognizer*)sender 
{ 
    .. 
} 

Ich möchte eine benutzerdefinierte Ansicht erstellen, die zoombar und ziehbar sein kann. Haben Sie eine Idee, dies bitte zu tun? (ohne Kopiercode ..)

Ich denke etwas wie Protokolle, aber ich möchte den Standardwert für die Basisklassen? Wie kann ich dies mithilfe von Protokoll oder etwas wie Protokolle implementieren.

Danke für jede Antwort!

+6

Objective-c keine Mehrfachvererbung nicht unterstützt, können Sie die beste Lösung Protokolle zu finden sein. –

+0

Wie kann ich das bitte umsetzen? Ich möchte keine Eigenschaft, die Delegat ist .. und ich möchte Standard-Wert zum Beispiel in Zoom-Ansicht Ich möchte Standard kleine Größe, wenn die Unterklasse nicht überschreiben die Funktion, die Klasse zurück (50,50). – Rebecca

+0

Es gibt keine wirklich gute Möglichkeit, Standardwerte für ein Protokoll festzulegen, da es nicht implementiert sein sollte. Was Sie tun könnten, ist, von einer Klasse zu erben, die das Protokoll implementiert, schauen Sie sich folgendes an: https://gist.github.com/paulrehkugler/9647085 –

Antwort

4

Am nächsten, dass Sie in Objective C zu Mehrfachvererbung gelangen können, ist mit Kategorien. Dies ist ein Mechanismus zum Hinzufügen zusätzlicher Methoden zu einer Klasse, die bereits existiert.

Beachten Sie, dass dies einige wichtige Einschränkungen:

  1. Sie können keine Eigenschaften hinzufügen oder ivars eine Kategorie verwenden, wenn Sie associated objects bekommen einen ähnlichen Effekt nutzen können;
  2. Der Compiler wird Ihnen nicht sagen, wenn Sie Methoden mit dem gleichen Namen haben, die in der Klasse und der Kategorie oder in zwei Kategorien deklariert sind, so müssen Sie vorsichtig sein, Namenskonflikte zu vermeiden;
  3. Dies wird nicht als eine richtige Klasse angezeigt (da Objective C nicht mehrfache Vererbung hat), so dass Sie nicht etwas in Ihrem Code ScrollableZoomableView haben, der von ScrollableView und ZoomableView erbt. Das ist in Objective C nicht möglich (im Gegensatz zu C++ zum Beispiel).
  4. Sie benötigen das -ObjC Flag beim Verknüpfen von Dateien mit Kategorien, sonst erhalten Sie unrecognized selector Fehler, wenn Sie Ihren Code ausführen;
  5. Sie können Ihren Code während -init oder +initialize nicht abrufen, da diese zur Basisklasse gehören. Sie müssen Ihre Eigenschaften explizit initialisieren. Sie können immer noch +load verwenden;
  6. Sie können Dealloc auch nicht abfangen, daher müssen Sie Ihre Listener ebenfalls explizit abmelden.

Sie wollen etwas wie folgt aus:

@interface UIView (Zoomable) 

@property (nonatomic) UITapGestureRecognizer * my_tapGestureRecognizer; 

@end 


@implementation UIView (Zoomable) 

-(void)my_enableZooming() { 
    self.my_tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(my_onDoubleTap:)]; 
    self.my_tapGestureRecognizer.numberOfTapsRequired = 2; 
    [self addGestureRecognizer:self.my_tapGestureRecognizer]; 
} 

-(void)my_disableZooming() { 
    [self removeGestureRecognizer:self.my_tapGestureRecognizer]; 
    self.my_tapGestureRecognizer = nil; 
} 

-(void)my_onDoubleTap:(UITapGestureRecognizer *)sender { 
    ... 
} 

-(UITapGestureRecognizer)my_tapGestureRecognizer { 
    return objc_getAssociatedObject(self, @selector(my_tapGestureRecognizer)); 
} 

-(void)setMy_tapGestureRecognizer:(UITapGestureRecognizer)value { 
    objc_setAssociatedObject(self, @selector(my_tapGestureRecognizer), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

@end 


@interface UIView (Draggable) 

@property (nonatomic) UIPanGestureRecognizer * my_panGestureRecognizer; 

@end 

@implementation UIView (Draggable) 

-(void)my_enableDragging() { 
    self.my_panGestureRecognizer = ...; 
} 

-(void)my_disableDragging() { 
    ... 
} 

-(void)my_handlePan:(UIPanGestureRecognizer*)sender { 
    ... 
} 

-(UIPanGestureRecognizer)my_panGestureRecognizer { 
    return objc_getAssociatedObject(self, @selector(my_panGestureRecognizer)); 
} 

-(void)setMy_panGestureRecognizer:(UIPanGestureRecognizer)value { 
    objc_setAssociatedObject(self, @selector(my_panGestureRecognizer), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

@end 
9

Objective-C nicht Mehrfachvererbung unterstützen. Sie können ein Protokoll, eine Komposition und eine Nachrichtenweiterleitung verwenden, um dasselbe Ergebnis zu erzielen.

Ein Protokoll definiert eine Reihe von Methoden, die ein Objekt implementieren muss (es ist auch möglich, optionale Methoden zu haben).Komposition ist im Grunde die Technik, einen Verweis auf ein anderes Objekt einzuschließen und dieses Objekt aufzurufen, wenn seine Funktionalität benötigt wird. Die Nachrichtenweiterleitung ist ein Mechanismus, mit dem Objekte Nachrichten an andere Objekte weiterleiten können, z. B. an ein Objekt, das über die Komposition eingefügt wird.

Apple-Referenz:

also in Ihrem Fall Zusammensetzung eine Lösung sein könnte, unter der Beispielcode ist

@interface ClassA : NSObject { 
} 

-(void)methodA; 

@end 

@interface ClassB : NSObject { 
} 

-(void)methodB; 

@end 

@interface MyClass : NSObject { 
    ClassA *a; 
    ClassB *b; 
} 

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB; 

-(void)methodA; 
-(void)methodB; 

@end 

@implementation MyClass 

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB { 
    a = anA ; 
    b = aB ; 
} 

-(void)methodA { 
    [a methodA] ; 
} 

-(void)methodB { 
    [b methodB] ; 
} 

@end 

Wenn Sie nicht alle Methoden aus ClassA und ClassB in MyClass implementieren möchten, können Sie die Nachrichtenweiterleitung in MyClass verwenden, um alle Methodenaufrufe zu verarbeiten. Unten funktioniert gut, solange ClassA und ClassB keine gemeinsamen Methoden haben.

@implementation MyClass 

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB { 
    a = anA ; 
    b = aB ; 
} 

//This method will be called, when MyClass can not handle the method itself 
-(void)forwardInvocation:(NSInvocation *)anInvocation 
{ 
    if ([a respondsToSelector:[anInvocation selector]]) 
     [a invokeWithTarget:someOtherObject]; 
    else if ([b respondsToSelector:[anInvocation selector]]) 
     [b invokeWithTarget:someOtherObject]; 
    else 
     [super forwardInvocation:anInvocation]; 
} 

@end 
2

Sie können sich auch diesen Artikel in objc.io über Verhaltensweisen ansehen. Sie können ziehbare und zoombare Verhaltensweisen erstellen und sie dann zu den gewünschten Ansichten hinzufügen.

Here's the article.