繁体   English   中英

目标c中的访问修饰符可见性

[英]Access modifier visibility in objective c

有3个修饰符:@ private,@ protected(默认)和@public。 因此,如果我将实例变量定义为私有,那么不应该从任何地方访问它。 对于Eg -

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

现在内部实现一些其他接口/类B-

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

在这里,我能够访问实例变量,虽然我将其定义为私有。

这有点令人困惑,虽然当我查看这个语句的细节时,很明显它正在调用a的getter,但是它也似乎令人困惑,它违背了OOPS的概念。

有没有想过这个?

它不是您正在访问的实例变量,而是您声明的属性。 如果您不希望实例变量在类外部可见,请不要声明该属性。

#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

直接访问@protected ivar

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

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

直接访问@private 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

因为您将其设置为@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的私有属性中查看更多详细信息

编辑:

感谢Abizern和Paul的评论,但事实上我没有为这个程序编译错误。

我认为RIP的问题是“为什么我在@private中设置变量,但我仍然可以修改变量,如instance.variable”

答案是尽管他将变量设置为@private,但在.h文件中声明@property变量也提供了公共方法getter和setter。 所以他仍然可以使用instance.variable获取实例变量。 对于OOP设计模式,您不应公开公开您的内部。 因此,如果您只想在其类中私有地使用变量,并且没有人知道它。 并且您仍然希望使用getter和setter来访问其类中的此变量。 你应该像我上面那样在.m文件中声明@property。 我在.m文件中声明了@property,它是一个@interface扩展名(未命名的类别)。 所以你可以让它“像”私人一样。 因为您无法从此类之外的任何位置访问此变量。 所以它就像我提到的“私人@property”。

两篇有用的文章公共属性与私人SetteriPhone的私有属性Objective-C

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM