Доступ к видимости модификатора в цели c - PullRequest
3 голосов
/ 08 января 2012

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

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

Теперь внутри реализации какого-то другого интерфейса / класса B-

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

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

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

Кто-нибудь задумывался об этом?

Ответы [ 3 ]

10 голосов
/ 08 января 2012

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

8 голосов
/ 08 января 2012
#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];
}

Давайте попробуем это

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

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

Прямой доступ к @public ivar

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

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

Доступ к @ защищенному ivar напрямую

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

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

Доступ к @ частному ivar напрямую

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
0 голосов
/ 08 января 2012

Потому что вы установили его как @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

Выможете проверить более подробно в Личные свойства для iPhone Objective-C

Редактировать:

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

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

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

Две полезные статьи для вас Открытые свойства с частными установщиками и Частные свойства для iPhone Objective-C

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...