美文网首页君赏博客
关于对类别 延展 协议 一些属性声明词的用法

关于对类别 延展 协议 一些属性声明词的用法

作者: 君赏 | 来源:发表于2015-06-17 16:33 被阅读305次

    什么是类别?

    类别是在现有类基础上,不改动现有的代码,增加新的功能。但是不能增加新的实例变量,但是可以通过runtime增加属性。
    解释这么多,说的都有点累。

    什么时候用类别呢?

    如果想给已经封装好的类添加方法 比如给UIButton添加一个异步下载图片的方法可以使用分类。比如我们要增加的方法需要实例变量很多 里面要用到很多的实例变量来执行逻辑 那么我们做好的选择是选择继承

    下面是例子

    #import <UIKit/UIKit.h>
    
    @interface UIButton (Add)
    {
    
            //没有办法添加实例变量
    }
    @property (nonatomic, assign) BOOL isHasImage;//可以通过这样添加
    @end
    
    #import "UIButton+Add.h"
    #import <objc/runtime.h>
    @implementation UIButton (Add)
    
    static char isHasImageKey;
    
    -(void)setIsHasImage:(BOOL)isHasImage{
    
            //因为必须传入一个ID 所以我们用NSNumber封装一下
        objc_setAssociatedObject(self, &isHasImage, [NSNumber numberWithBool:isHasImage], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    -(BOOL)isHasImage{
    
        return  [objc_getAssociatedObject(self, &isHasImageKey) boolValue];
    }
    @end
    

    如果我们基类是自己写的 现在想要给基类扩展方法 我们都知道类别对基类所有类型的实例变量都有访问的权限 我们可以无限制的添加类别 我们只需要在之前基类添加所需要的实例变量

    #import <Foundation/Foundation.h>
    @interface Class1 : NSObject{
    
    
    }
    
    @end
    
    @interface Class1 (Class5)
    
    -(void)_init;
    @end
    
    
    @interface Class1 (Class6)
    
    
    
    @end
    
    #import <Foundation/Foundation.h>
    @interface Class1 : NSObject{
    
    
    }
    
    @end
    
    @interface Class1 (Class5)
    
    -(void)_init;
    @end
    
    
    @interface Class1 (Class6)
    
    
    
    @end
    

    我们可以在之前的类里面进行分类 这样的话和系统的看一起一样的。

    延展

    我们可以直接把延展写在基类,但是有一些私有的方法和属性将不能被看到。如果我们希望声明的方法被看到,但是无法被调用 我们可以新建一个延展的.h文件

    
    @public//可以在子类和本类,实例变量类调用 在子类和本类内部可以用直接调用 用实例变量需要用->
    @package//这个在制作frameWork的时候经常的用到 在framework他的作用于和@protected一样,在外部和@private一样的 比如UIButton用@package声明的变量只能在framework的自己类和子类用到 我们创建UIButton的子类无法调用 并且分类也没办法使用
    @protected//只能在自己类和子类内部使用 实例变量无法调用
    
    @private//只能自己类内部可以调用
    

    协议

    我们一般定义协议用于获取数据和代理出去方法

    用DataSource获取数据
    用Delegate代理出去方法(你也可以用这个获取数据)

    我们可以给基类添加类别 实现自己要实现代理的方法

    @protocol Class1Delegate <NSObject>
    
    -(void)method;
    
    @end
    

    我们在class1添加了一个代理 我们想让UIButton去实现

    我们可以添加一个类别

    -(void)doDelegateMethod;
    

    添加一个方法去执行代理

    -(void)doDelegateMethod{
    
        if (_delegate && [_delegate respondsToSelector:@selector(method)]) {
            [_delegate method];
        }
    }
    

    新增加一个UIButton的分类

    #import <UIKit/UIKit.h>
    #import "Class1.h"
    @interface UIButton (Category)<Class1Delegate>
    @end
    
    
    #import "UIButton+Category.h"
    
    @implementation UIButton (Category)
    -(void)method{
    
        NSLog(@"这是Class1的代理方法");
    }
    @end
    

    创建实例变量

    UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
    
        class->_delegate=button;
    
    
        [class doDelegateMethod];
    

    好了讲述了基本的关键字作用域还有分类 延展 协议三个用法 写的头都大了

    如果说的有错误 请及时的联系我

    相关文章

      网友评论

        本文标题:关于对类别 延展 协议 一些属性声明词的用法

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