OC中没有绝对的私有变量和私有方法
- 对于私有变量,例如在.h文件中使用
@private
修饰的变量;在.m文件中扩展中声明的变量和属性和方法默认都是@private
私有的- 对于私有方法,在.h文件中没有声明,在.m文件中只做了实现的方法是私有的
看上去这些变量属性和方法都是私有的,实际可以通过一些手段强制进行访问,因此OC中没有绝对的私有
私有变量强制访问
.h文件
#import <Foundation/Foundation.h>
@interface TestObject : NSObject
{
@private
NSString *major;//私有成员变量
}
@end
.m文件
@interface TestObject()
{
int age;//私有成员变量
}
@property (nonatomic,copy)NSString *name;//私有属性
@end
@implementation TestObject
- (void)test {//私有方法
NSLog(@"这是一个私有方法");
}
@end
> 方式一:通过kvc强制访问私有属性和成员变量
TestObject *test = [[TestObject alloc]init];
[test setValue:@"albert" forKeyPath:@"name"];
NSString *name = [test valueForKey:@"name"];
NSLog(@"%@",name);
> 方式二:通过runtime强制访问私有属性和成员变量
TestObject *test = [[TestObject alloc]init];
unsigned int count = 0;
Ivar *members = class_copyIvarList([TestObject class], &count);
Ivar varName = members[3];
Ivar varMajor = members[0];
object_setIvar(test, varName, @"binbin");
object_setIvar(test, varMajor, @"shuoshuo");
NSString *name = object_getIvar(test, varName);
NSLog(@"%@",name);
free(members);
私有方法强制访问
TestObject *test = [[TestObject alloc]init];
unsigned int count = 0;
Method *methods = class_copyMethodList([TestObject class], &count);
SEL sel = method_getName(methods[0]);
[test performSelector:sel];
⚠️[test performSelector:sel];
此句代码会报警告,警告调用了一个未知的方法
❗️那么如何消除这个警告,此处就需要使用分类的一个作用,即分类可以创建对私有方法的前向引用
创建分类,并在.h文件中将宿主类的私有方法声明在这里
.h文件
#import "TestObject.h"
NS_ASSUME_NONNULL_BEGIN
@interface TestObject (Category)
- (void)testMethod;
@end
NS_ASSUME_NONNULL_END
.m文件中不用做任何实现
此时在其他文件中引用分类.h文件和宿主类.h文件,然后直接调用私有方法即可
TestObject *test = [[TestObject alloc]init];
[test testMethod];