概念
分类(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
|