iOS开发笔记之七十——如何访问对象的私有方法和变量

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


再构造MDFather的子类MDSon如下:

.h文件如下:

#import "MDFather.h"

@interface MDSon : MDFather

@end
.m文件如下:

#import "MDSon.h"

@implementation MDSon

@end


二、初始化MDSon如下:

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的动态特性,我们可以达到这一目的。


猜你喜欢

转载自blog.csdn.net/lizitao/article/details/79251999