Objective-C对象的分类

2018-06-30  本文已影响41人  紫荆秋雪_文

一、Objective-C对象的分类

Objective-C中的对象,简称OC对象,主要可以分为3种

二、instance对象

1、instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象

// RevanPerson
#import <Foundation/Foundation.h>

@interface RevanPerson : NSObject {
    @public
    int _age;
}

@end

// ViewController
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSObject *obj = [[NSObject alloc] init];
    RevanPerson *person = [[RevanPerson alloc] init];
    person->_age = 18;
    NSLog(@"%@\n%@", obj, person);
}

@end

2、instance对象在内存中存储的信息包含

3、class对象(类对象)在内存中存储的信息

#import "ViewController.h"
#import "RevanPerson.h"

#import <objc/runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSObject *obj1 = [[NSObject alloc] init];
    NSObject *obj2 = [[NSObject alloc] init];
    
    Class obj_class1 = [obj1 class];
    Class obj_class2 = [obj2 class];
    Class obj_class3 = [NSObject class];
    
    //使用 runtime 获取[实例对象]的[类对象]
    Class obj_class4 = object_getClass(obj1);
    Class obj_class5 = object_getClass(obj2);
    
    NSLog(@"\n%p\n%p\n%p\n%p\n%p\n", obj_class1, obj_class2, obj_class3, obj_class4, obj_class5);
}

@end
打印输出:
0x106cdeea8
0x106cdeea8
0x106cdeea8
0x106cdeea8
0x106cdeea8

4、meta-class


#import "ViewController.h"
#import "RevanPerson.h"
#import <objc/runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSObject *revan_obj = [[NSObject alloc] init];
    RevanPerson *revan_person = [[RevanPerson alloc] init];
    
    Class NSObjectClass = [NSObject class];//类对象
    Class NSObjectClass1 = object_getClass(revan_obj);//类对象(runtime)
    Class NSObjectMetaClass = object_getClass(NSObjectClass);//元类对象(runtime)
    
    NSLog(@"\nNSObjectClass:%p\nNSObjectClass1:%p\nNSObjectMetaClass:%p\n", NSObjectClass, NSObjectClass1, NSObjectMetaClass);
    
    
    Class RevanPersonClass = [RevanPerson class];//类对象
    Class RevanPersonClass1 = object_getClass(revan_person);//类对象(runtime)
    Class RevanPersonMetaClass = object_getClass(RevanPersonClass);//元类对象(runtime)
    NSLog(@"\nRevanPersonClass:%p\nRevanPersonClass1:%p\nRevanPersonMetaClass:%p\n", RevanPersonClass, RevanPersonClass1, RevanPersonMetaClass);
}
@end

输出打印:
NSObjectClass:0x11099cea8
NSObjectClass1:0x11099cea8
NSObjectMetaClass:0x11099ce58

RevanPersonClass:0x10f9f2ee0
RevanPersonClass1:0x10f9f2ee0
RevanPersonMetaClass:0x10f9f2eb8

三、isa指针

在instance对象、class对象、meta-class对象的内存存储中都有一个isa指针,那么isa指针有什么用?

1、isa指针在instance对象中的作用 类的instance对象&class对象&meta-class对象.png

/***********  RevanPerson  *************/
#import <Foundation/Foundation.h>

@interface RevanPerson : NSObject

- (void)instanceRevanPersonFun;
@end


#import "RevanPerson.h"

@implementation RevanPerson

@end

/***********  测试 instance对象调用对象方法  *************/
#import "ViewController.h"
#import "RevanPerson.h"
#import <objc/runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //instance对象
    RevanPerson *revan_p = [[RevanPerson alloc] init];
    //instance对象对用方法
    [revan_p instanceRevanPersonFun];
}
@end

2、isa指针在class对象中的作用

/************ RevanPerson *************/
#import <Foundation/Foundation.h>

@interface RevanPerson : NSObject

/**
 对象方法
 */
- (void)instanceRevanPersonFun;
/**
 类方法
 */
+ (void)classRevanPersonFun;
@end

#import "RevanPerson.h"

@implementation RevanPerson

@end


/************ 测试代码 ************/
#import "ViewController.h"
#import "RevanPerson.h"
#import <objc/runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //调用类方法
    [RevanPerson classRevanPersonFun];
}
@end

四、superclass指针

通过创建RevanStudent类、RevanPerson类、NSObject类来分析superclass,并且RevanStudent类继承于RevanPerson类,RevanPerson类继承于NSObject superclass.png

1、RevanStudent类的instance对象调用自己类中的对象方法在上面已经分析过了,由于RevanStudent类继承于RevanPerson类,那么RevanStudent类的instance对象可以调用RevanPerson类中的对象方法,同理也可以调用NSObject类中的对象方法,这个过程是如何完成的

/************ RevanPerson *************/
#import <Foundation/Foundation.h>

@interface RevanPerson : NSObject

/**
 对象方法
 */
- (void)instance_RevanPersonFun;
@end

#import "RevanPerson.h"

@implementation RevanPerson
/**
 对象方法
 */
- (void)instance_RevanPersonFun {
    NSLog(@"instance_RevanPersonFun");
}
@end


/************ RevanPerson *************/
#import "RevanPerson.h"

@interface RevanStudent : RevanPerson

/**
 对象方法
 */
- (void)instance_RevanStudentFun;
@end

#import "RevanStudent.h"

@implementation RevanStudent

/**
 对象方法
 */
- (void)instance_RevanStudentFun {
    NSLog(@"instance_RevanStudentFun");
}

@end

/************ 测试代码 ************/

#import "ViewController.h"
#import "RevanPerson.h"
#import "RevanStudent.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //创建revan_s
    RevanStudent *revan_s = [[RevanStudent alloc] init];
    //调用父类对象方法
    [revan_s instance_RevanPersonFun];
}
@end

输出打印:
instance_RevanPersonFun(RevanPerson类中的对象方法的输出)

2、meta-class对象中的superclass


/************ RevanStudent *************/
#import "RevanPerson.h"

@interface RevanStudent : RevanPerson

/**
 对象方法
 */
- (void)instance_RevanStudentFun;

/**
 类方法
 */
+ (void)class_RevanStudentFun;
@end
#import "RevanStudent.h"

@implementation RevanStudent

/**
 对象方法
 */
- (void)instance_RevanStudentFun {
    NSLog(@"instance_RevanStudentFun");
}

/**
 类方法
 */
+ (void)class_RevanStudentFun {
    NSLog(@"class_RevanStudentFun");
}
@end


/************ RevanPerson *************/
#import <Foundation/Foundation.h>

@interface RevanPerson : NSObject

/**
 对象方法
 */
- (void)instance_RevanPersonFun;
/**
 类方法
 */
+ (void)class_RevanPersonFun;
@end

#import "RevanPerson.h"

@implementation RevanPerson
/**
 对象方法
 */
- (void)instance_RevanPersonFun {
    NSLog(@"instance_RevanPersonFun");
}

/**
 类方法
 */
+ (void)class_RevanPersonFun {
    NSLog(@"class_RevanPersonFun");
}

@end


/************ 测试代码 ************/

#import "ViewController.h"
#import "RevanPerson.h"
#import "RevanStudent.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //调用父类的类方法
    [RevanStudent class_RevanPersonFun];
}
@end

打印输出:
class_RevanPersonFun(RevanPerson的类方法)

五、总结 isa&&superclass.png

isa&&superclass.png
上一篇 下一篇

猜你喜欢

热点阅读