2016-05-24 12 views
0

Ich habe eine benutzerdefinierte Unterklasse von NSPopUpButtonCell, so dass ich seine drawBezelWithFrame:inView: Methode überschreiben kann.Wie kann ich ein NSCoding-konformes Objekt in eine Unterklasse klonen?

Derzeit muss ich eine neue Instanz erstellen mit initTextCell:pullsDown: und kopieren Sie dann alle seine Eigenschaften von Hand. Das ist ziemlich mühsam und fehleranfällig, da mir einige Eigenschaften fehlen könnten.

Ich frage mich, ob ich stattdessen initWithCoder: für diese Aufgabe verwenden kann. Ich stelle mir vor, ich sollte in der Lage sein, die Daten von der bestehenden NSPopUpButtonCell Instanz in ein NSCoder Objekt, z. in NSKeyedArchiver, und dann diese Daten zurück in meine Unterklasse NSPopUpButtonCell. Aber ich kann mir nicht vorstellen, wie ich das erreichen soll.

+0

Wie erstellen Sie den Popup-Button, programmgesteuert oder XIB? – Willeke

+0

@Willeke Von einer Feder, und ich lernte, dass ich das bestimmte leichter lösen konnte. Dennoch möchte ich gerne herausfinden, ob es möglich ist, ein Objekt in einer Unterklasse zu klonen. –

Antwort

0

Sieht so aus, als hätte ich vorher nur die falschen Funktionen benutzt. Die Entscheidung ist ziemlich geradlinig.

Dieser Code kopiert die Eigenschaften eines NSPopUpButtonCell in eine Unterklasse davon, so dass ich seine Draw ... Methoden überschreiben kann:

@interface MyPopup : NSPopUpButton 
@end 

@implementation MyPopup 
- (instancetype)initWithCoder:(NSCoder *)coder { 
    self = [super initWithCoder:coder]; 
    if (self) { 
     // Set up the archiver 
     NSMutableData *data = [NSMutableData data]; 
     NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
     // Archive the cell's properties 
     [self.cell encodeWithCoder:arch]; 
     [arch finishEncoding]; 
     // Set up the unarchiver 
     NSKeyedUnarchiver *ua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
     // Create a subclass of the cell's class, using the same properties 
     MyCell *newCell = [[MyCell alloc] initWithCoder:ua]; 
     // Assign the new subclass object as the NSButton's cell. 
     self.cell = newCell; 
    } 
    return self; 
} 

Ein weitere, saubere Weise eine benutzerdefinierte NSButtonCell Unterklasse zu verwenden, wird gezeigt, hier: Using full width of NSPopupButton for text, no arrows

1

Wenn Ihre gesamte Unterklasse Methoden überschreibt, d. H. Keine zusätzlichen Felder hinzufügt, können Sie die Klasse Ihrer ursprünglichen NSPopupButtonCell oder eine Kopie davon überschreiben, so dass sie zur Instanz Ihrer Unterklasse wird.

Apple implementiert KVO mit dieser Technik, in diesem Fall mit einer dynamisch generierten Unterklasse. Wenn Ihr Fall ist die Unterklasse statisch ist, so dass es viel einfacher, die Umrisse des Codes ist:

object_setClass(<an NSPopupButtonCell instance>, 
       [<your subclass> class]); 

Wenn Sie sicher die Klasse auf der ursprünglichen Instanz ändern können, dann handelt es sich dabei keine Objekterstellung oder das Kopieren überhaupt.

Erinnern Sie sich können nur tun, wenn die Unterklasse Verhalten nur ändert.

Für eine andere Erklärung siehe this answer.

HTH