美文网首页
类目 延展 协议

类目 延展 协议

作者: Maj_sunshine | 来源:发表于2017-06-21 21:33 被阅读14次

前言

Objective-C中提供了可以让我们扩展类定义的手段:类目,延展和协议。类目:为已知的类增加新的方法;延展:通知在本类的定义里使用类目来声明私有方法;协议:协议声明了可以被任何类实现的方法。
注意:这些手段只能增加类的方法,并不能用于增加实例变量,要增加类的实例变量,只能通过定义子类来间接实现。

类目

类目的目的和使用
1 将类的实现分散到不同文件或者不同框架中。

之前看过一个大神的文章说到,在控制器在尽量不要写入类创建的大量代码,比如button,UIView,Label的创建,最好在项目工程中将这些创建代码写入类目中,也是为了代码重用,毕竟这些基础创建代码写多会看到一堆。都写入控制器会导致控制器臃肿,MVC是个重控制器的架构模式,本身控制器就相对其他模块代码多的多。

- (void)createLabel
{
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100,100 , 100)];
    [self.view addSubview:label];
    label.text = @"类目的使用";
    label.font = [UIFont systemFontOfSize:14];
    label.textColor = [UIColor blackColor];
    label.layer.cornerRadius = 7;
    label.layer.masksToBounds = YES;
    label.textAlignment = NSTextAlignmentLeft;
}
像这种代码在项目中频繁出现,不仅会污染代码,写多了也会累

创建类目来简化和解耦

#import <UIKit/UIKit.h>

@interface UILabel (Create)
+(UILabel *)initWithFrame:(CGRect)frame text :(NSString *)text font :(UIFont*)font textColor :(UIColor *)color textAlignment :(NSTextAlignment)textAlignment cornerRadius :(NSInteger)cornerRadius masksToBounds :(BOOL)masksToBounds;
@end

#import "UILabel+Create.h"

@implementation UILabel (Create)



+(UILabel *)initWithFrame:(CGRect)frame text:(NSString *)text font:(UIFont *)font textColor:(UIColor *)color textAlignment:(NSTextAlignment)textAlignment cornerRadius:(NSInteger)cornerRadius masksToBounds:(BOOL)masksToBounds
{
    return [[self alloc]initWithFrame:frame text:text font:font textColor:color textAlignment:textAlignment cornerRadius:cornerRadius masksToBounds:masksToBounds];
}

-(instancetype)initWithFrame:(CGRect)frame text:(NSString *)text font:(UIFont *)font textColor:(UIColor *)color textAlignment:(NSTextAlignment)textAlignment cornerRadius:(NSInteger)cornerRadius masksToBounds:(BOOL)masksToBounds
{
    self = [super init];
    if (self) {
        self.frame = frame;
        self.text = text;
        self.textAlignment = textAlignment;
        self.textColor =color;
        self.font = font;
        self.layer.cornerRadius = cornerRadius;
        self.layer.masksToBounds = masksToBounds;
    }
    return self;
}

@end
使用
- (void)createLabel
{
    UILabel *label = [UILabel initWithFrame:CGRectMake(100, 100,100 , 100) text:@"类目的使用" font:[UIFont systemFontOfSize:14] textColor:[UIColor blackColor] textAlignment:NSTextAlignmentLeft cornerRadius:7 masksToBounds:YES];
    [self.view addSubview:label];
}
2 创建对私有方法的向前引用。

即将类的方法声明写在了类目.h中,后在要引用的.m文件处加入头文件声明类目方法的存在,若没有向前引用,则原有类并不知道存在类目中方法,这时就不能调用

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

现在已经被正式协议代替。

延展

延展相当于一个匿名的类目,可以在延展中使用@property生成类的属性,会自动生成get和set方法,该属性不会被外部调用,隐藏在.m文件为私有属性,默认修饰符private。也可以在延展中声明方法,但该方法的实现必须在改类中。

延展在代码中可以写为

@interface testViewController ()    //testViewController为类名
//- (void)test ;

@end

一般创建一个继承于UIViewController的类时在.m文件中会自动创建,若类不存在延展,又需要私有属性,则需要以上方法。

协议

协议顾名思义就是定义了一套规则供他人使用。举一个例子,假如你现在在公司 ,你老板早上要求你下午干两件事情

1 打电话给顾客
2 代替老板发工资给员工

在需要传值的类.h文件头加
@protocol nextDelegate<NSObject>
- (void)callToCustomerWithPhone :(NSString *)phoneStr;
- (void)postSalaryToWorkers :(NSInteger) Count;
@end
//typedef void(^backBlock)(NSString *str);
@interface NextViewController : UIViewController

@property(nonatomic,weak) id<nextDelegate> delegate;  //要用weak修饰符弱引用,strong会造成循环引用
//@property(nonatomic,copy) backBlock Block;   //block使用copy修饰符

作为协议的两个方法

老板作为委托人,就需要告诉你打什么电话和发多少工资

即在需要传值的类.m文件中确定传值对象

 - (void)pop
{
   //写委托的时候确定 代理签定方是否实现了方法 否则程序奔溃, 可以使用- (BOOL)respondsToSelector:(SEL)aSelector;  检查是否实现了方法,若确定实现方法,可以去掉条件框。
    if ([_delegate respondsToSelector:@selector(callToCustomerWithPhone:)]) {
        [_delegate callToCustomerWithPhone:@"13555555555"];
    }
    if ([_delegate respondsToSelector:@selector(postSalaryToWorkers:)]) {
        [_delegate postSalaryToWorkers:10000];
    }
    //block回调时也要注意是否实现了回调的方法 ,若没有实现也没有下面安全检测,也会奔溃
   // if (_Block) {
   //      _Block(@"pop");
//    }
    
    [self.navigationController popViewControllerAnimated:YES];
}


终于老板把任务和任务的具体数字交代给了你,你要做的第一件事就是是否要领这个任务签这个协议 ,签了协议就意味着你一定要做上面两样工作。

签订协议 ,我在push时签订协议,则在pop时候能回调协议方法
- (void)pushNext
{
    NextViewController *next = [[NextViewController alloc]init];
    next.delegate = self;  //代理协议要签订,不然代理方法不调用
    [self.navigationController pushViewController:next animated:YES];
  //  next.Block = ^(NSString *str)
  //  {
  //     
//    };
}

实现协议 
#pragma nextDelegate

- (void)postSalaryToWorkers:(NSInteger)Count
{
    
}

- (void)callToCustomerWithPhone:(NSString *)phoneStr
{
    
}

delegate设计模式和block方法比较

delegate 更重一些,需要实现接口,它的方法分离开来。另外相关的代码会被分离到各处,没有 block 好读。代理的回调函数可以是一组多个函数,不同情况下调用不同的函数

block 更轻型,使用更简单。使用 block 的代码通常会在同一个地方,这样读代码也连贯。

另:block外部使用__week修饰会防止循环引用
但是在block里面在强引用一下是为了防止变量提前释放(例如block里面有延迟调用的方法,强引用的变量是一个局部变量,出了block就会释放)

勉励:对于攀登者来说,失掉往昔的足迹并不可惜,迷失了继续前时的方向却很危险。

相关文章

  • 类目 延展 协议

    前言 Objective-C中提供了可以让我们扩展类定义的手段:类目,延展和协议。类目:为已知的类增加新的方法;延...

  • iOS类目、延展、协议

    1.类目 类目就是为已存在的类添加新的方法。但是不能添加实例变量。比如系统的类,我们看不到他的.m文件,所以没有办...

  • UI(十)类目延展协议

    协议类目延展 #pragma mark---协议---- *协议:正式协议<协议名>是一个公共接口文件,只要遵守...

  • 类别(category)延展(extension)

    Objective-c中提供了可以让我们扩展类定义的手段:类目,延展和协议。类目:为已知的类增加新的方法;延展:通...

  • iOS类目、延展和协议

    类目### 为已知的类添加新的方法。(已知类包括自己定义的类和系统已有的类)类目的目的 1.将类的实现分散到多个不...

  • 类目,延展,和协议,代理

    为什么使用类目是一种为现有的类添加新方法的方式有时需要对现有的类添加一些方法,之前都是通过继承相关的类,然后再子类...

  • Objective-C 「类目、延展、协议」

    类目(Category) (1).为已知的类添加新的方法,无论是否知道类的源代码,这些类包括自己定义的类和系统已有...

  • 类目(Category),延展(Extension),协议(Pr

    1. 类目(Category) 类目: 又称"分类", 为已知的类(系统或自己创建的类)添加新的方法 1.1 类目...

  • Objective-c:类目、延展、协议

    概述 OC用于拓展已存在类的内置功能是它最强大的功能之一。类目、延展、协议提供了可以让你扩展类功能的方式。使用他们...

  • 类目、延展

    目录:1、类目2、延展 1、类目(类别)Category 1.从定义看类目就是给类来添加一个眼睛?,哈哈,其实就是...

网友评论

      本文标题: 类目 延展 协议

      本文链接:https://www.haomeiwen.com/subject/ongdzttx.html