概念
分类(Category)是OC中的特有语法,它是表示一个指向分类的结构体的指针。分类允许你将方法添加到现有的类中,甚至可以添加到你没有源代码的类中。分类是一项强大的功能,可让你扩展现有类的功能而无需子类化。使用分类,你还可以在几个文件中分配自己的类的实现。
Human.h
#import <Foundation/Foundation.h>
@interface Human : NSObject
@property(nonatomic,copy)NSString *humanPublicName;
- (void) say;
@end 
Human.m
#import "Human.h"
@interface Human ()
@property(nonatomic,copy)NSString *humanPrivateName;
@end
@implementation Human
- (void)say {
    NSLog(@"%@",self);
}
@end 
programmer.h
//
//  programmer.h
//  test-callback
//
//  Created by nan on 2022/3/29.
//
#ifndef programmer_h
#define programmer_h
#import "Human.h"
@interface Programmer : Human
@property(nonatomic,copy)NSString *programmPublicName;
-(void)say;
@end
#endif /* programmer_h */
 
Programmer.m
//
//  programmer.m
//  test-callback
//
//  Created by nan on 2022/3/29.
//
#import <Foundation/Foundation.h>
#import "Programmer.h"
//类扩展(匿名分类)
@interface Programmer ()
@property(nonatomic,copy) NSString *programmerPrivateName;
@end
@implementation Programmer
-(void)say
{
    NSLog(@"Programmer中的say方法");
}
@end
 
Programmer+Category.h
//
//  Programmer+Category.h
//  test-callback
//
//  Created by nan on 2022/3/29.
//
#ifndef Programmer_Category_h
#define Programmer_Category_h
#import "Programmer.h"
@interface Programmer (Category)
@property(nonatomic,copy) NSString *nameWithSetterGetter;           //设置setter/getter方法的属性
@property(nonatomic,copy) NSString *nameWithoutSetterGetter;        //不设置setter/getter方法的属性,注意编译的警告部分
- (void) programCategoryMethod;                                     //分类方法
-(void)say;
@end
#endif /* Programmer_Category_h */
 
Programmer+Category.m
//
//  Programmer+Category.m
//  test-callback
//
//  Created by nan on 2022/3/29.
//
#import <Foundation/Foundation.h>
#import "Programmer+Category.h"
#import <objc/runtime.h>
static NSString *nameWithSetterGetterKey = @"nameWithSetterGetterKey";
@implementation Programmer (Category)
-(void)say
{
    NSLog(@"Programmer+Private中的say方法");
}
- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter {
        objc_setAssociatedObject(self, &nameWithSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY);
}
- (NSString *)nameWithSetterGetter {
    return objc_getAssociatedObject(self, &nameWithSetterGetterKey);
}
- (void)programCategoryMethod {
    NSLog(@"实现分类方法");
}
@end
 
ViewController.m
//
//  ViewController.m
//  test-callback
//
//  Created by nan on 2021/12/8.
//
#import "ViewController.h"
#import "Human.h"
#import "Programmer.h"
#import "Programmer+Category.h"
@interface ViewController ()
@end
@implementation ViewController
-(void)messageCallBack:(NSString *)string
{
//self.textView.text=string;
}
-(void)test_category{
    Human *h = [[Human alloc]init];
    h.humanPublicName = @"Person的publicName";
    Programmer *programmer = [[Programmer alloc]init];
    //通过runtime实现了setter/getter
    programmer.nameWithSetterGetter = @"有setter/getter";    //调用setter,成功
    NSLog(@"%@",programmer.nameWithSetterGetter);            //调用getter,成功
    //NSLog(@"%@",programmer._nameWithSetterGetter); //这是调用_成员变量,错误提示为:(Use of undeclared identifier '_nameWithSetterGetter')
    //普通声明,无setter/getter
    //programmer.nameWithoutSetterGetter = @"无setter/getter";    //调用setter,编译成功,运行报错为:(-[Programmer setNameWithSetterGetter:]: unrecognized selector sent to instance 0x7f9de358fd70')
    //NSLog(@"%@",programmer.nameWithoutSetterGetter);   //调用getter,编译成功,运行报错为-[Programmer setNameWithSetterGetter:]: unrecognized selector sent to instance 0x7fe22be11ea0'
  
    //    调用的是分类的say方法,主类的say被隐藏了
    [programmer say];
    //    分类的方法实现
    [programmer programCategoryMethod];
}
- (void)viewDidLoad {
    [super viewDidLoad];
   // self.textView.text=@"测试";
    [self test_category];
    
    // Do any additional setup after loading the view.
}
@end










