iOS开发之category(类别)

首先,category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改,并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。

类别主要有3个作用:

1).将类的实现分散到多个不同文件或多个不同框架中。

2).创建对私有方法的前向引用。

3).向对象添加非正式协议。

继承可以增加,修改或者删除方法,并且可以增加属性。

一.通过理解category的概率我们来增加类的方法(项目中常用的category)

//十六进制颜色的类别

    label.backgroundColor = [UIColor colorWithHexString:@"#0387EC" alpha:1.0];

//注册和忘记密码的倒计时

 [self.verifyCodeBtn countDownFromTime:60 title:@"获取验证码" unitTitle:@"" mainColor:[UIColor clearColor] countColor:[UIColor clearColor]];

//常用第三方库(MJRefresh)的头部刷新

WEAK_SELF; 
self.MainTableView.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
       
        [weakSelf DataRefresh];
        
      [weakSelf.MainTableView.header endRefreshing];
    }];

//第三方库yy_modelWithJSON方法

selfModel *list = [selfModel yy_modelWithJSON:responseObj];

当然还有很多,这里先列举我本人常用的几个。

现在就以扩展UIButton的一个倒计时方法为例子:

建一个UIButton的Category

 

 最后就是在刚才这个category的.m文件里实现这个方法了

@implementation UIButton (countdownButton)

- (void)countDownFromTime:(NSInteger)startTime title:(NSString *)title unitTitle:(NSString *)unitTitle mainColor:(UIColor *)mColor countColor:(UIColor *)color {
    
    __weak typeof(self) weakSelf = self;
    
    // 剩余的时间
    __block NSInteger remainTime = startTime;
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    // 每秒执行一次
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    
    // 子线程(queue)执行event_handler
    dispatch_source_set_event_handler(timer, ^{
        
        if (remainTime <= 0) { // 倒计时结束
            dispatch_source_cancel(timer);
            // 主线程更新UI
            dispatch_async(dispatch_get_main_queue(), ^{
                weakSelf.backgroundColor = mColor;
                [weakSelf setTitle:title forState:UIControlStateNormal];
                weakSelf.enabled = YES;
            });
        } else {
            NSString *timeStr = [NSString stringWithFormat:@"%ld", remainTime];
            dispatch_async(dispatch_get_main_queue(), ^{
                weakSelf.backgroundColor = color;
                [weakSelf setTitle:[NSString stringWithFormat:@"%@%@",timeStr,unitTitle] forState:UIControlStateDisabled];
                weakSelf.enabled = NO;
            });
            remainTime--;
        }
    });
    dispatch_resume(timer);
}


@end

然后到要需要的类里面调用这个扩展的方法就可以了。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"category";
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(60, 260, 300, 30)];
    label.text = @"I am a Label";
    label.backgroundColor = [UIColor colorWithHexString:@"#0387EC" alpha:1.0];
    label.textColor = [UIColor whiteColor];
    label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:label];
    
    
    verifyCodeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    verifyCodeBtn.frame = CGRectMake(60,360,300,40);
    [verifyCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
    verifyCodeBtn.titleLabel.font = [UIFont systemFontOfSize:12];
    [verifyCodeBtn setTitleColor:[UIColor colorWithHexString:@"#0387EC" alpha:1.0f] forState:UIControlStateNormal];
    [verifyCodeBtn addTarget:self action:@selector(codeSendCode:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:verifyCodeBtn];
    
}
-(void)codeSendCode:(UIButton *)sender {
    
    [verifyCodeBtn countDownFromTime:60 title:@"获取验证码" unitTitle:@"" mainColor:[UIColor clearColor] countColor:[UIColor clearColor]];
}

展示一下出来的效果

 

 剩下三种就不一一展示了。

二.我们来看看category的作用

   1.将类的实现分散到多个不同文件或多个不同框架中。

   一般,我们在使用类的时候,我们将类的接口放入.h文件上,而将类的实现放在.m文件中,但不可能将@implementation分散到多个不同的.m文件中。而类别就只要你在需要使用的类或者框架中导入.h,就可以将类的实现分散到多个不同文件或多个不同框架中去。

  2.创建对私有方法的向前引用。

  类中的私有方法访问不了,如果强行访问,会报错。这个时候可以使用类别来声明这个方法(不必提供方法实现),编译器就不会再产生警告

#import <UIKit/UIKit.h>

@interface PsonVC : UIViewController

- (void)PublicMethod; //公开方法,可在其他类或子类进行访问

@end

#import "PsonVC.h"

@interface PsonVC ()

- (void)PrivateMethod;//在类延展中定义的是私有方法

@end

@implementation PsonVC

- (void)PublicMethod //.h中有申明,公开方法
{
     NSLog(@"这是公有方法,其他类可以调用");
}
- (void)PrivateMethod {//类延展中有申明,私有方法
    
     NSLog(@"这是私有方法,其他类无法调用");

如果没写类别,在别的类中,是调用不了私有方法的;

 

 在psonVC类的类别中,声明方法的话,那在别的类中调用不会产生警告和报错。这就是创建对私有方法的向前引用。

3.向对象添加非正式协议:非正式协议是NSObject类(显而易见,还包括它的子类)的类别,其所有的子类都含蓄地接受了这个协议。所谓的非正式协议就是类别,即凡是NSObject或其子类的类别,都是非正式协议。创建一个NSObject的类别称为 “创建一个非正式协议”,因为可以作为任何类的委托对象使用。

posted @ 2020-04-17 22:50  朝阳向日葵  阅读(746)  评论(0编辑  收藏  举报