问题描述
尝试使用KVC访问ivars之后,我注意到私有和受保护的ivars上没有任何保护.放在ivar前面(私有或保护关键字)没有关系-使用KVC方法"setValue"时,ivar始终是公共ivar.这是我的代码,其中七个ivar和属性在类实例之外都可以更改:
After trying to access ivars using KVC, I have noticed that there was no protection on private and protected ivars. It doesn't matter what I put a in front of the ivar (private or protected keyword) - an ivar is always a public ivar when using KVC method "setValue". Here is my code where all of the seven ivars and properties are changeble outside the class instance:
//************ interface file ***************//
@interface MyClass : NSObject {
@public
NSNumber *public_num;
@protected
NSNumber *protected_num;
@private
NSNumber *private_num;
NSNumber *private_property;
}
@property (retain) NSNumber *public_property;
@property (retain) NSNumber *private_property;
@end
//********* implementation file *********//
@interface MyClass(){
@private
NSNumber *very_private_num;
}
@property (retain) NSNumber *very_private_property;
@end
@implementation MyClass
@synthesize public_property, private_property, very_private_property;
@end
//****** main **********//
MyClass *myClass = [[MyClass alloc] init];
[myClass setValue:[NSNumber numberWithInt:1] forKey:@"public_num"];
[myClass setValue:[NSNumber numberWithInt:2] forKey:@"protected_num"];
[myClass setValue:[NSNumber numberWithInt:3] forKey:@"private_num"];
[myClass setValue:[NSNumber numberWithInt:4] forKey:@"public_property"];
[myClass setValue:[NSNumber numberWithInt:5] forKey:@"private_property"];
[myClass setValue:[NSNumber numberWithInt:6] forKey:@"very_private_num"];
[myClass setValue:[NSNumber numberWithInt:7] forKey:@"very_private_property"];
NSNumber *l_public_num = [myClass valueForKey:@"public_num"];
NSNumber *l_protected_num = [myClass valueForKey:@"protected_num"];
NSNumber *l_private_num = [myClass valueForKey:@"private_num"];
NSNumber *l_public_property = [myClass valueForKey:@"public_property"];
NSNumber *l_private_property = [myClass valueForKey:@"private_property"];
NSNumber *l_very_private_num = [myClass valueForKey:@"very_private_num"];
NSNumber *l_very_private_property = [myClass valueForKey:@"very_private_property"];
NSLog(@"public_num = %@, protected_num = %@, private_num = %@, public_property = %@, private_property = %@, very_private_num = %@, very_private_property = %@", l_public_num, l_protected_num, l_private_num, l_public_property, l_private_property, l_very_private_num, l_very_private_property);
输出结果> public_num = 1,protected_num = 2,private_num = 3,public_property = 4,private_property = 5,very_private_num = 6,very_private_property =7.
The result of the output> public_num = 1, protected_num = 2, private_num = 3, public_property = 4, private_property = 5, very_private_num = 6, very_private_property = 7.
即使ivar在私有接口上声明,它在类外部仍然可以更改.因此,我必须如何强制执行封装并保护自己的ivars免受邪恶的其他程序员的侵害" :)
Even if the ivar declared at private interface, it is still changeable outside the class. So how do I have to enforce encapsulation and "to protect my ivars from evil other programmers" :)
推荐答案
NSObject符合 NSKeyValueCoding 非正式协议.这定义了setValue:forKey:
和valueForKey:
. setValue:forKey:
和valueForKey:
根据特定的搜索规则,其中包括直接访问实例变量.这种直接访问是由accessInstanceVariablesDirectly
方法控制的,该方法是NSKeyValueCoding非正式协议的一部分,该协议默认情况下返回YES
,从而允许这些方法直接访问实例变量,因此实际上并没有使它们私有.他们仍然对直接访问不公开.
NSObject conforms to the NSKeyValueCoding informal protocol. This defines setValue:forKey:
and valueForKey:
. setValue:forKey:
and valueForKey:
search for a way to access the value of the key according to specific search rules which includes directly accessing the instance variable. This direct accessing is controlled by accessInstanceVariablesDirectly
method which is a part of the NSKeyValueCoding informal protocol, which by default returns YES
, allowing those methods to directly access the instance variables and as a result not really making them private as such. They are still private from direct access.
要解决此问题,您将必须覆盖上述方法和NSKeyValueCoding
非正式协议中定义的方法,以防止它们被访问.
To resolve this, you will have have to override the methods mentioned above and defined in the NSKeyValueCoding
informal protocol to prevent their access.
如Abizern所述,由于Objective-C没有私有方法的概念,私有变量的属性仍然可以访问.
As mentioned by Abizern, properties for private variables are still accessible since Objective-C has no concept of private methods.
这篇关于Objective-C:为什么在使用KVC时不从外部访问隐藏私有ivars的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!