首先,私有的定义:是指只能够在本类内部使用或访问,但是不能在类的外部被访问。
但oc是动态性语言,它的对象类型和要调用的方法都是再运行中才能确定的,也就决定了在oc中没有绝对的私有变量和私有方法的
访问私有变量
1、在知道变量名称时,可以通过kvc
来直接访问和改变私有变量
2、通过runtime
获得所有的成员变量列表
下面我们来验证下
#import "Person.h"
@interface Person (){
@private
NSString *name;
NSString *sex;
}
@end
@implementation Person
- (void)test{
NSLog(@"私有方法");
}
@end
调用
//1、通过kvc访问
Person *person = [[Person alloc] init];
[person setValue:@"krys" forKey:@"name"];
[person setValue:@"男" forKey:@"sex"];
NSLog(@"name = %@,sex = %@",[person valueForKey:@"name"],[person valueForKey:@"sex"]);
//2、通过runtime访问
unsigned int outCount = 0;
Ivar *ivars =class_copyIvarList([Person class], &outCount);
for (int i = 0; i < outCount; i++) {
Ivar ivar = ivars[i];
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
NSString *value = object_getIvar(person, ivar);
NSLog(@"key = %@,value = %@",key,value);
}
打印出的结果
2019-09-25 15:24:51.544623+0800 Demo[22831:5169456] name = krys,sex = 男
2019-09-25 15:24:51.544694+0800 Demo[22831:5169456] key = name,value = krys
2019-09-25 15:24:51.544731+0800 Demo[22831:5169456] key = sex,value = 男
那么访问私有方法呢
1、在知道方法的名称以及参数的前提下通过performSelector
系列方法访问
2、通过runtime
获取方法列表
3、使用category
,上面的Person
类中test方法为例,给Person
增加个category
,若category
声明的方法和Person
类中方法名相同,且category
并未实现此方法,则会去类里查找这个方法调用
我们同样用上面的Person
类来验证
//1、通过performSelector
Class c = NSClassFromString(@"Person");
NSObject *obj = [[c alloc] init];
SEL method = NSSelectorFromString(@"test");
[obj performSelector:method withObject:nil afterDelay:YES];
//2、通过runtime
Method *methods = class_copyMethodList([Person class], &outCount);
for (int i = 0; i < outCount; i++) {
Method method = methods[i];
SEL methodSel = method_getName(method);
NSString *sel = [NSString stringWithCString:methodSel encoding:NSUTF8StringEncoding];
NSLog(@"sel = %@",sel);
}
打印出的结果
2019-09-25 15:34:21.881038+0800 Demo[22834:5170995] 私有方法
2019-09-25 15:44:28.663878+0800 Demo[22846:5173445] sel = test
以上,我们自然可以得出自己的结论了