Objective-C对象的变量和方法本身其实没有绝对的私有和公有之分。我们可以利用OC的runtime动态特性,访问对象的方法和属性。
我们可以结合以下实例方法演示如下:
一、我们构造父类MDFather如下:
.h文件如下
#import <Foundation/Foundation.h> @interface MDFather : NSObject @end
.m文件如下:
#import "MDFather.h" @interface MDFather () @property (nonatomic, strong) NSString *name; @end @implementation MDFather - (id)init { if(self = [super init]) { _name = @"lizitao"; } return self; } - (void)printName { NSLog(@"%@",_name); } - (void)printName:(NSString *)name { NSLog(@"base run with %@", name); } @end
.h文件如下:
#import "MDFather.h" @interface MDSon : MDFather @end.m文件如下:
#import "MDSon.h" @implementation MDSon @end
MDSon *son = [MDSon new];1、利用objc_msgSend()方法直接调用:
objc_msgSend(son, @selector(printName:), @"hello world...");注意:如果objc_msgSend()方法有系统报错,可以Build Settings中设置如下:
如果有如下警告,也可以采用如下方法让编译器警告闭嘴:
2、performSelector调用方法:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" if ([son respondsToSelector:@selector(printName:)]) { [son performSelector:@selector(printName:) withObject:@"hello world..."]; } #pragma clang diagnostic pop
3、SEL获取方法的的IMP:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" SEL selector = @selector(printName); IMP method = [son methodForSelector:selector]; method(); #pragma clang diagnostic pop
4、调用属性变量:
利用object_getInstanceVariable获取son对象的属性变量,如下:
Ivar nameIvar = class_getInstanceVariable([son class], "_name"); NSString *name = object_getIvar(son, nameIvar); NSLog(@"name: %@", name);
在业务开发中,一般不提倡破坏对象的封装性,但是有时业务开发需要(解耦等),利用OC的动态特性,我们可以达到这一目的。