本文介绍了Objective-C:为什么在使用KVC时不从外部访问隐藏私有ivars的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 06:49