Що @private
означає "Objective-C"?
Що @private
означає "Objective-C"?
Відповіді:
Це модифікатор видимості - це означає, що змінні екземплярів, оголошені як, @private
можуть бути доступні лише екземпляри одного класу . До приватних членів не можна отримати доступ до підкласів або інших класів.
Наприклад:
@interface MyClass : NSObject
{
@private
int someVar; // Can only be accessed by instances of MyClass
@public
int aPublicVar; // Can be accessed by any object
}
@end
Крім того, для уточнення, в Objective-C методи завжди є загальнодоступними. Однак існують способи "приховування" декларацій методів - для отримання додаткової інформації див. Це питання .
Як сказав htw, це модифікатор видимості. @private
означає, що ivar (змінна інстанція) може бути доступна лише безпосередньо з екземпляра цього ж класу. Однак це для вас може не означати багато чого, тому дозвольте навести вам приклад. Ми будемо використовувати init
методи класів як приклади, для простоти. Я буду коментувати на черзі, щоб вказати на цікаві речі.
@interface MyFirstClass : NSObject
{
@public
int publicNumber;
@protected // Protected is the default
char protectedLetter;
@private
BOOL privateBool;
}
@end
@implementation MyFirstClass
- (id)init {
if (self = [super init]) {
publicNumber = 3;
protectedLetter = 'Q';
privateBool = NO;
}
return self;
}
@end
@interface MySecondClass : MyFirstClass // Note the inheritance
{
@private
double secondClassCitizen;
}
@end
@implementation MySecondClass
- (id)init {
if (self = [super init]) {
// We can access publicNumber because it's public;
// ANYONE can access it.
publicNumber = 5;
// We can access protectedLetter because it's protected
// and it is declared by a superclass; @protected variables
// are available to subclasses.
protectedLetter = 'z';
// We can't access privateBool because it's private;
// only methods of the class that declared privateBool
// can use it
privateBool = NO; // COMPILER ERROR HERE
// We can access secondClassCitizen directly because we
// declared it; even though it's private, we can get it.
secondClassCitizen = 5.2;
}
return self;
}
@interface SomeOtherClass : NSObject
{
MySecondClass *other;
}
@end
@implementation SomeOtherClass
- (id)init {
if (self = [super init]) {
other = [[MySecondClass alloc] init];
// Neither MyFirstClass nor MySecondClass provided any
// accessor methods, so if we're going to access any ivars
// we'll have to do it directly, like this:
other->publicNumber = 42;
// If we try to use direct access on any other ivars,
// the compiler won't let us
other->protectedLetter = 'M'; // COMPILER ERROR HERE
other->privateBool = YES; // COMPILER ERROR HERE
other->secondClassCitizen = 1.2; // COMPILER ERROR HERE
}
return self;
}
Отже, щоб відповісти на ваше запитання, @private захищає ivars від доступу екземпляром будь-якого іншого класу. Зауважте, що два екземпляри MyFirstClass могли отримати доступ до всіх ivars один одного; передбачається, що оскільки програміст має повний контроль над цим класом, він розумно буде використовувати цю здатність.
@private
в шаблоні для об'єкта, це вже не так рідко.
@implementation
блоці. І коли ви це зробите, вони фактично є приватними незалежно від модифікаторів видимості, оскільки їх навіть не видно нікому поза цим файлом.
Важливо зрозуміти, що це означає, коли хтось каже, що ви не можете отримати доступ до @private
змінної екземпляра. Справжня історія полягає в тому, що компілятор дасть вам помилку, якщо ви спробуєте отримати доступ до цих змінних у своєму вихідному коді. У попередніх версіях GCC та XCode ви отримаєте попередження замість помилки.
Так чи інакше, на час виконання всі ставки вимикаються. До них @private
і @protected
ivars можна отримати доступ будь-якого класу. Ці модифікатори видимості просто ускладнюють складання вихідного коду до машинного коду, що порушує наміри модифікаторів видимості.
Не покладайтесь на модифікатори видимості ivar для безпеки! Їх взагалі немає. Вони призначені виключно для виконання бажань класного будівельника під час складання.