objective-c中的分类

概念

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值