2016-06-24 12 views
2

Vor einigen Tagen wechselte ich zu Swift-Codierung nach objc. Und wenn ich Adapter mit MVVM-Muster schreibe, verwechselte ich mit dem nächsten Fall, was ohne Probleme in objc gemacht werden konnte.Schnelle Inhärenz Aufgabe

So in ObjC: Wir haben IDTableViewController mit Moderator (Ansichtsmodell) Immobilie

@interface IDTableViewController : UITableViewController 
    @property (nonatomic, strong) id<IDCollectionPresenterProtocol> presenter; 
@end 

Und wenn wir IDTableViewController erben, wir Klasse von Moderator in Verlängerung außer Kraft setzen (was natürlich zu Protokoll oben erwähnt entspricht)

UsersViewController.h 
@interface UsersViewController : IDTableViewController 

UsersViewController.m 
@interface UsersViewController() 
    @property (nonatomic, strong) UsersPresenter *presenter; 
@end 

@implementation UsersViewController 
@dynamic presenter; 

Und alles ist gut ... Aber in Swift kann ich nicht das Gleiche tun. Ich kann die Klasse der Eigenschaft in UsersViewController nicht überschreiben

class IDTableViewController: UITableViewController { 

    var viewModel : IDCollectionPresenterProtocol? 
} 
class UsersViewController: IDTableViewController { 

    var viewModel : UsersPresenter? 
} 

Kann ich das tun? Und wie könnte ich es umsetzen, wenn es nicht legal ist?

Antwort

0

Es gibt ein paar Ansätze:

  1. Sie können gespeicherte Eigenschaft mit berechneten Eigenschaft überschreiben, dass ein Front-End auf dem eigenen Grundstück zB gespeichert ist:

    class UsersViewController: IDTableViewController { 
        private var usersViewModel: UsersPresenter? 
        override var viewModel: IDCollectionPresenterProtocol? { 
         get { return usersViewModel } 
         set { usersViewModel = newValue as! UsersPresenter } 
        } 
    } 
    
  2. Sie könnten Überschreiben Sie viewModel überhaupt nicht und implementieren Sie einfach usersViewModel als eine berechnete Eigenschaft selbst, wenn Sie eine UsersPresenter Schnittstelle zum Ansichtsmodell innerhalb von UsersViewController benötigen:

    class UsersViewController: IDTableViewController { 
        private var usersViewModel: UsersPresenter? { 
         get { return viewModel as? UsersPresenter } 
         set { viewModel = newValue } 
        } 
    } 
    

Die anderen, natürlich Swifty Wege des Umgangs mit dieser (z.B. Generics oder Protokoll mit Standardimplementierungen der UITableViewDataSource Methoden in einer Protokollerweiterung) spielen nicht gut mit Objective-C, so dass Sie Probleme haben werden, wenn Sie sie als View-Controller oder als verwenden.

+0

Vielen Dank, berechnet Privateigentum ist was ich brauche. :) – qub

0

So etwas könnte sein, was Sie wollen:

protocol MyProtocol { 

} 

class ImplementedProtocol : MyProtocol { 

} 

class MyBaseClass<T : MyProtocol> { 
    var viewModel : T? 
} 

class MyDerivedClass : MyBaseClass<ImplementedProtocol> { 

} 

Wenn Sie jetzt instanziiert MyDerivedClass, viewModelImplementedProtocol vom Typ sein. Ein Wort der Warnung: Xcode 7.3 hat den Typ von viewModel in der Autovervollständigung nicht korrekt abgeleitet, sondern es einer Variablen zugewiesen, die fest ist - also ist es nur ein Xcode-Bug, der hoffentlich bald behoben sein wird.

+0

Wenn wir in einer rein schnellen Welt leben, stimme ich zu, dass dies ein guter Weg ist, es zu tun. Das Problem ist, dass Generika in Objective-C nicht dargestellt werden können und daher Versuche, Generics für einen View-Controller und/oder 'UITableViewDataSource' zu ​​verwenden, nicht funktionieren. – Rob

+0

Ah ja, Interop mit Ziel-C ist natürlich ein Problem. Es ist einer der Schmerzen, mit denen wir im Moment leben müssen :( –