2012-01-08 2 views
3

Существует 3 модификатора: @private, @protected (по умолчанию) и @public. Поэтому, если я определяю переменную экземпляра как приватную, то она не должна быть доступна нигде. . -Видимость модификатора доступа в объекте c

@interface A { 
    @private 
    NSString *a; 
} 
@property(nonatomic, retain) NSString *a; 

Сейчас в реализации какого-либо другого интерфейса/класса B-

-(void)getSomeValue { 
    A *object = [[A alloc] init]; 
    NSString *value = object.a; 
    ......... 
} 

Здесь я могу получить доступ к переменной экземпляра, хотя я определил, что как частные.

Это немного запутанно, хотя, когда я заглядываю в детали этого утверждения, тогда ясно, что он вызывает геттер a, но тогда он также кажется запутанным и противоречит концепции OOPS.

У кого-нибудь задумался об этом?

+1

И @package, которая ограничивает видимость рамки. – Abizern

ответ

10

Это не переменная экземпляра, к которой вы обращаетесь, но свойство, которое вы объявили. Не объявляйте свойство, если вы не хотите, чтобы переменная экземпляра была видна вне класса.

+0

Мой вопрос в основном, если я могу получить доступ к закрытой переменной вне того, что это значимость? – rishi

+9

Опять же, вы не получаете доступ к частной переменной. Вы объявили это свойством этого класса. Таким образом, вы создали геттер и сеттер для него. Переменная по-прежнему является частной. Способы доступа - нет. – tobiasbayer

+1

CodeBrickie - Спасибо .. я получил его ... я думаю, что я немного смущен синтаксисом ... – rishi

-2

Поскольку вы устанавливаете его как свойство @property и утверждаете его в файле заголовка. Переменная, которую вы задали как @property, автоматически сгенерирует getter и setter для этой переменной, и они являются общедоступным методом для ее получения или установки (переменная по-прежнему является частной). Если вы действительно хотите сделать свойство приватным методом, вы должны его утвердить в файле .m, и он станет закрытым. Вы можете использовать эту переменную только в файле .m.

Например, в вашем файле .h

@interface ClassWithPrivateProperty : NSObject { 
@private 
    NSString* member; 
} 
- (void) trySettingPrivateProperty; 
@end 

в файле .m

#import "ClassWithPrivateProperty.h" 

@interface ClassWithPrivateProperty() 
@property (nonatomic,retain) NSString* member; 
@end 

@implementation ClassWithPrivateProperty 
@synthesize member; 
- (void) trySettingPrivateProperty { 
    self.member = @"A Value"; 
    NSLog(@"myClass.member = %@", self.member); 
} 
@end 

Вы можете проверить более подробную информацию в Private properties for iPhone Objective-C

Edit:

Спасибо за Абизерн и комментарий Павла, но на самом деле я не получил ничего компиляции ошибки для этой прогры м.

Я думаю, что вопрос RIP является «Почему я установить переменную в @private, но я все еще могу изменить переменную как instance.variable»

Ответ хотя он установил переменную как @private, но претензии @property для переменной в файле .h также предоставляют общедоступные методы getter и setter. Поэтому он все еще может использовать переменную экземпляра instance.variable. Для шаблона проектирования ООП вы не должны публично публиковать свои внутренности. Поэтому, если вы хотите использовать переменную конфиденциально только в своем классе, и никто ее не знает. И вы все равно хотите использовать getter и setter для доступа к этой переменной в своем классе. вы должны требовать @property в .m файле, как я сделал выше. Я утверждаю @property в .m файле, это расширение @interface (безымянная категория). Таким образом, вы можете сделать это «как» частным. Потому что вы не можете получить доступ к этой переменной из любого места вне этого класса. Так что это как «частный @property», о котором я упоминаю.

две полезные статьи для вас Public Properties with Private Setters и Private properties for iPhone Objective-C

+3

Вы не можете создавать частные '@ property'. Вы можете скрыть его видимость, но нет ничего, что могло бы заставить меня вызвать «член экземпляра»; «из любого места». –

+0

Пол прав. Вы получите предупреждение о компиляторе, но нет ничего, чтобы предотвратить отправку сообщения. – Abizern

8
#import <Foundation/Foundation.h> 

@interface Visibility : NSObject { 
@public  
    BOOL boolPublic; 
@protected 
    BOOL boolProtected; 
@private 
BOOL boolPrivate; 
} 

@property (nonatomic, assign) BOOL boolPublic; 
@property (nonatomic, assign) BOOL boolProtected; 
@property (nonatomic, assign) BOOL boolPrivate; 

@end 

@implementation Visibility 

@synthesize boolPublic; 
@synthesize boolProtected; 
@synthesize boolPrivate; 

@end 

int main(int argc, char *argv[]) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    Visibility *visibility = [[Visibility alloc] init]; 

    visibility.boolPublic = YES; 
    visibility.boolProtected = YES; 
    visibility.boolPrivate = YES; 

    // Place following NSLog()'s here 

    [pool release]; 
} 

Давайте попробовать это

Используя методы, которые определяют с @ собственности/@ синтезируют

NSLog(@"Accessors %d %d %d", visibility.boolPublic, visibility.boolProtected, visibility.boolPrivate); 

=> 2012-01-08 17:46:40.226 Untitled[2592:707] Accessors 1 1 1 

Доступ @ общественный ivar напрямую

NSLog(@"Public %d", visibility->boolPublic); 

=> 2012-01-08 17:46:40.228 Untitled[2592:707] Public 1 

Доступ @protected Ивар непосредственно

NSLog(@"Protected %d", visibility->boolProtected); 

=> error: instance variable 'boolProtected' is protected 
=> NSLog(@"Protected %d", visibility->boolProtected); 
=>         ^

Доступ @private Ивар непосредственно

NSLog(@"Private %d", visibility->boolPrivate); 

=> error: instance variable 'boolPrivate' is private 
=> NSLog(@"Private %d", visibility->boolPrivate); 
=>        ^

Когда вы обращаетесь с помощью точечной нотации это:

visibility.boolPublic 

эквивалентно:

[visibility boolPublic]; // <- This is a method call 
Смежные вопросы