proprietate privată în Objective C (Programare, Obiectiv C)

Yurie a intrebat.

Există o modalitate de a declara o proprietate privată în Objective C? Scopul este de a beneficia de getters și setters sintetizate care implementează o anumită schemă de gestionare a memoriei, dar nu sunt expuse la public.

O încercare de a declara o proprietate în cadrul unei categorii duce la o eroare:

@interface MyClass : NSObject {
    NSArray *_someArray;
}

...

@end

@interface MyClass (private)

@property (nonatomic, retain) NSArray   *someArray;

@end

@implementation MyClass (private)

@synthesize someArray = _someArray;
// ^^^ error here: @synthesize not allowed in a category's implementation

@end

@implementation MyClass

...

@end

Comentarii

  • De ce să aveți o proprietate privată? Când puteți accesa pur și simplu proprietatea *_someArray direct în cadrul metodelor de instanță? –  > Por Broasca neagră.
  • Posibil Dup stackoverflow.com/questions/3665698/… – –  > Por Brook.
  • Proprietățile private sunt un loc excelent pentru a pune lucruri precum logica de încărcare leneșă pentru ivars –  > Por Michael Lang.
4 răspunsuri
Mark Adams

Eu îmi implementez proprietățile private astfel.

MyClass.m

@interface MyClass ()

@property (nonatomic, retain) NSArray *someArray;

@end

@implementation MyClass

@synthesize someArray;

...

Asta e tot ce ai nevoie.

Comentarii

  • Pentru a extinde acest lucru, Objective-C nu are cu adevărat conceptul de metode private. Puteți apela orice metodă doriți, atâta timp cât îi cunoașteți numele. Aceasta este ceea ce vă permite să apelați metode private în clasele Apple, chiar dacă acestea nu există în anteturi. –  > Por Todd Yandell.
  • 33

  • „Asta e tot ce vă trebuie.” 😀 Niciodată nu am folosit atât de mult cod pentru a defini doar o simplă proprietate –  > Por stoefln.
  • În zilele noastre nici măcar nu mai ai nevoie de @synthesize. –  > Por Supă.
  • Credeam că trebuie să declari proprietățile în fișierul .h? –  > Por cheznead.
  • Asigurați-vă că nu setați un nume pe categoria dvs. în fișierul .m, astfel @interface MyClass (DontPutMeHere)în caz contrar, sintetizarea automată nu va funcționa –  > Por Christoph.
Ospho

A. Dacă doriți o variabilă complet privată. Nu-i dați o proprietate.
B. Dacă doriți o variabilă readonly care să fie accesibilă din exteriorul încapsulării clasei, utilizați o combinație între variabila globală și proprietatea:

//Header    
@interface Class{     
     NSObject *_aProperty     
}

@property (nonatomic, readonly) NSObject *aProperty;

// In the implementation    
@synthesize aProperty = _aProperty; //Naming convention prefix _ supported 2012 by Apple.

Folosind modificatorul readonly putem acum să accesăm proprietatea de oriunde din exterior.

Class *c = [[Class alloc]init];    
NSObject *obj = c.aProperty;     //Readonly

Dar, la nivel intern, nu putem seta o proprietate în interiorul clasei:

// In the implementation    
self.aProperty = [[NSObject alloc]init]; //Gives Compiler warning. Cannot write to property because of readonly modifier.

//Solution:
_aProperty = [[NSObject alloc]init]; //Bypass property and access the global variable directly

Anomie

Depinde ce înțelegeți prin „privat”.

Dacă vă referiți doar la „nu este documentat public”, puteți utiliza destul de ușor un extensie de clasă într-un antet privat sau în fișierul .m.

Dacă vă referiți la „alții nu o pot apela deloc”, nu aveți noroc. Oricine poate apela metoda dacă îi cunoaște numele, chiar dacă nu este documentată public.

Comentarii

  • > „Oricine poate apela metoda dacă îi cunoaște numele, chiar dacă nu este documentată public.” – Calculul securizat în cea mai bună formă 🙁 –  > Por Bron Davies.
  • @BronDavies objective-c folosește paradigma „mesageriei” în care trimiteți mesaje către un obiect. Numele proprietății este doar conținutul mesajului, iar valoarea proprietății este doar răspunsul obiectului la mesaj. Dacă doriți securitate cu orice sistem de mesagerie, trebuie să folosiți criptarea. Numele proprietății ar putea fi derivat dintr-o cheie privată și poate că se schimbă la fiecare 30 de secunde. Securitatea este cu siguranță posibilă în obj-c dacă aveți nevoie de ea. Totuși, nu-mi pot imagina de ce ați avea nevoie… Eu îmi fac proprietățile private, astfel încât să le pot schimba mai târziu fără a sparge codul extern. –  > Por Abhi Beckert.
Rog

Așa cum au indicat și alții, (în prezent) nu există nicio modalitate de a declara cu adevărat o proprietate privată în Objetive-C.

Unul dintre lucrurile pe care le puteți face pentru a încerca să „protejați” proprietățile cumva este să aveți o clasă de bază cu proprietatea declarată ca fiind readonly iar în subclasele dvs. puteți declara din nou aceeași proprietate ca fiind readwrite.

Documentația Apple privind proprietățile redeclarate poate fi găsită aici: http://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW19

Comentarii

  • Am constatat că utilizarea {} a fost puțin complicată și am vrut doar să subliniez acest lucru aici; în fișierul .m a trebuit să declar proprietatea „privată”. după blocul {}; (scuzați formatul prost…) @interface MyClass() { SKProductsRequest* _request; NSMutableArray* _productLocales; } @property (strong, nonatomic) SKProductsRequest *request; @end @implementation MyClass @synthesize request = _request; ... –  > Por SonarJetLens.