Ich möchte den Zugriff auf NSMutableArray in der öffentlichen Schnittstelle
schützenIch versuche dies zu tun, indem ich die Eigenschaft als NSArray in der öffentlichen Schnittstelle und als NSMutableArray in der privaten Schnittstelle wie folgt definiere:
%Vor%Aber das funktioniert nicht - also muss ich stattdessen die Eigenschaft in der öffentlichen Schnittstelle NSMutableArray definieren:
%Vor% Das Ziel besteht darin, schreibgeschützten Zugriff auf Kommentare für API-Clients und vollständigen Zugriff auf Methoden wie addObject:
in der Implementierung bereitzustellen.
So definieren Sie das Ziel klarer:
Also einfach die Frage war, ob es möglich ist, die Definition von Eigenschaften allgemeiner zu machen (NSArray statt NSMutableArray).
Gibt es einen anderen sauberen Weg, um das Ziel zu erreichen, oder muss ich überall NSMutableArray verwenden?
Lösung
Nachdem ich meine ursprüngliche Frage und Antworten gelesen hatte, wurde mir klar, dass ich in der öffentlichen Schnittstelle NSCrypt und in der Implementierung NSMutableArray verwenden möchte - aber für eine Eigenschaft ist das nicht möglich. Also die Antwort ist nicht möglich.
Also werde ich einfach eine Eigenschaft mit NSMutableArray ohne zusätzlichen Schutz verwenden.
Aber ich wähle auch die am besten geeignete Antwort aus, wenn Sie wirklich Schutz vor Einfachheit und Effizienz bevorzugen.
Sie benötigen keine öffentliche Eigenschaft , wenn Sie nur Clients das Lesen des Arrays erlauben möchten.
Erstellen Sie einfach eine Zugriffsmethode, die eine Kopie Ihres privaten änderbaren Arrays zurückgibt:
%Vor% Dieses Muster kann z. B. in NSView
: constraints
und subviews
intern geändert werden, aber nur zum Lesen über eine einzige Methode verfügbar gemacht werden, die ein nicht veränderbares Array zurückgibt.
Eine Lösung wäre, die Eigenschaft als schreibgeschützt als NSArray
zu deklarieren. Erstellen Sie dann in Ihrer Implementierung eine separate, schreibbare Eigenschaft basierend auf NSMutableArray
.
In der .h:
%Vor%In der .m:
%Vor%Anstatt die schreibgeschützte Eigenschaft zu synthetisieren, schreiben Sie:
%Vor% In der .m machst du alles mit self.internalComments
.
Eine weit sauberere Lösung wäre, wenn es für Ihren Anwendungsfall akzeptabel wäre, die Eigenschaft als NSArray
zu deklarieren, während sie mit einem NSMutableArray
unterstützt wird. Der Client könnte das Array technisch modifizieren, indem er es einfach in ein änderbares Array umwandelt, aber Sie machen deutlich, dass dies eine schlechte Idee wäre.
A @property
ist einfach ein Wrapper um zwei Methoden, einen Getter und einen Setter, die typischerweise von einer Speichervariablen unterstützt werden. Der einfachste Weg, diese Lösung zu implementieren, wäre:
Wenn Sie möchten, dass der Benutzer das gesamte Array ersetzen kann ( order.comments = ...
), entfernen Sie das Attribut readonly
für die Eigenschaft und überschreiben Sie die Methode -setComments:
:
Da Objective-C eine dynamische Sprache ist, ist es nicht möglich, den Zugriff einer Person auf eine Variable vollständig zu verhindern, da Sie Schnittstelle direkt mit der Laufzeit oder Aufruf Methoden von ihrem Selektor, wenn Sie wirklich in Dingen herumstochern wollen, die Sie nicht sind sollst. Alles, was Sie wirklich tun können, ist klarzustellen, dass dies eine schlechte Idee ist.
Wenn Sie nicht möchten, dass der Client diese Eigenschaft überhaupt festlegen kann, deklarieren Sie ihn in der öffentlichen Schnittstelle als readonly
. Wenn Sie nicht möchten, dass der Client das vom Client gelesene Array mutieren kann, deklarieren Sie es als NSArray. Inzwischen sind Sie auf Ihrer Seite readwrite
und copy
. Wenn Sie readwrite
verwenden, können Sie ein mutableCopy
(was ein NSMutableArray sein soll) übernehmen, Ihre Änderungen vornehmen und dann die Eigenschaft erneut festlegen. Indem Sie copy
angeben, stellen Sie sicher, dass der Client immer ein NSArray sieht.
Also, Kunde:
%Vor%Innenauftrag:
%Vor%Tags und Links objective-c cocoa design encapsulation declared-property