有三个修饰符:@private、@protected(默认值)和@public。因此,如果我将实例变量定义为private,那么它不应该从任何地方访问。例如-
@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/@synthesis中定义的方法
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的变量将自动为此变量生成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文件中声明了@属性,它是一个@接口扩展名(未命名类别)。所以你可以让它"像"私人。因为您无法从此类之外的任何位置访问此变量。所以它就像我提到的"私人财产"。
两篇有用的文章为您提供了带有Private Setters的Public Properties和iPhone Objective-C 的Private Properties