iOS面试剖析

私有变量和私有方法的访问

2019-02-13  本文已影响0人  滨滨_57b5

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];此句代码会报警告,警告调用了一个未知的方法

image.png
❗️那么如何消除这个警告,此处就需要使用分类的一个作用,即分类可以创建对私有方法的前向引用
创建分类,并在.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];
上一篇 下一篇

猜你喜欢

热点阅读