zoukankan      html  css  js  c++  java
  • category中添加属性的简单方式

    一、概念扩充:

    1、如我们所知,使用category是用来对现有类进行功能扩展,或者将类分成多模块的一种方式。由声明和实现两部分组成。可以单独写成Objiective-C File类型文件(包含.h和.m)。

    2、category可以用来给现有类添加新的方法。

    3、category不可以给类添加成员,会直接报错(编译不过)。

    4、category可以用@property来添加属性,此种方式会自动生成对应属性的set和get方法的声明,但是没有set和get方法的实现,也不会自动生成带有“_”的属性。

    5、category添加的属性使用点语法无效,原因如上。

    二、如何实现给category添加可以使用的属性

     案例一:

     1、给UIView类中添加4个属性,用来获得和更改控件frame的x,y,width,height。正常开发中,我们无法直接通过点语法来给一个控件的frame中x,y,width,height直接进行赋值操作,因为frame是CGRect类型的结构体,其中的两个成员origin和 size也是结构体类型。我们通过给UIView写一个category来实现这一操作。

    (1)在category的声明中添加4个新属性:

    #import <UIKit/UIKit.h>
    
    @interface UIView (EXTFrame)
    
    @property (nonatomic,assign) CGFloat x;
    
    @property (nonatomic,assign) CGFloat y;
    
    @property (nonatomic,assign) CGFloat width;
    
    @property (nonatomic,assign) CGFloat height;
    
    @end

    (2)在category的实现中进行set和get方法的重写:

    #import "UIView+EXTFrame.h"
    
    @implementation UIView (EXTFrame)
    
    
    -(void)setX:(CGFloat)x
    {
        CGRect rect = self.frame;   
        rect.origin.x=x;
        self.frame = rect;
    }
    
    -(CGFloat)x
    {
      return self.frame.origin.x;
    }
    
    -(void)setY:(CGFloat)y
    {   
        CGRect rect = self.frame;
        rect.origin.y=y;
        self.frame=rect;
    }
    
    -(CGFloat)y
    {
        return self.frame.origin.y;
    }
    
    -(void)setWidth:(CGFloat)width
    {   
        CGRect rect = self.frame;
        rect.size.width=width;
        self.frame=rect;
    }
    
    -(CGFloat)width
    {
       return self.frame.size.width;  
    }
    
    -(void)setHeight:(CGFloat)height
    {
        CGRect rect = self.frame;
        rect.size.height=height;
        self.frame=rect;
    }
    
    -(CGFloat)height
    {
        return self.frame.size.height; 
    }

    (3)虽然category不会生成带有“_”的属性,并不是代表set和get不可用,创建完category后,在后面开发过程中,只要包含了category头文件,同时继承于UIView的类的对象,均可以直接使用点语法获得和更改x,y,width,height,比如:MyImageView.x=50,可以非常方便的给控件的frame做改动。

    案例二:

    1、给UIView类添加name属性,通过关联对象(运行时机制)增加属性。

    运行时实现功能:

    ———>运行时能够给正在运行的对象添加属性。

    ———>运行时能够获取正在运行的对象的所有属性。

    ———>运行时能够用来交换方法。

    (1)在category的声明中添加name属性:

    #import <UIKit/UIKit.h>
    
    @interface UIView (EXTName)
    
    @property(nonatomic,copy) NSString * name;
    
    @end

    (2)在category的实现中通过运行时重写属性的set和get,要求包含objc框架里的runtime.h头文件。

    #import "UIView+EXTName.h"
    #import <objc/runtime.h>
    @implementation UIView (EXTName)
    -(void)setName:(NSString *)name
    {
        //self表示正在运行的对象,“NAME”是C的标识,name为添加的新属性的值,最后一个参数是属性修饰符(枚举)
        objc_setAssociatedObject(self, "NAME", name, OBJC_ASSOCIATION_COPY_NONATOMIC );
    }
    
    -(NSString *)name
    {
        return objc_getAssociatedObject(self, "NAME");
    }
    @end

    (3)添加完此category后,UI控件可以通过点语法直接访问和设置“name”属性。

  • 相关阅读:
    Android属性动画之ValueAnimation
    Android属性动画之第一重修炼总结
    Android属性动画之ObjectAnimator控制
    Android属性动画之ObjectAnimator
    HDU 4334——Trouble——————【贪心&水题】
    HDU 5416——CRB and Tree——————【DFS搜树】
    HDU 4323——Magic Number——————【dp求编辑距离】2012——MUT——3
    HDU 5384——Danganronpa——————【AC自动机】
    HDU——Cover——————【技巧】
    CF 540D——Bad Luck Island——————【概率dp】
  • 原文地址:https://www.cnblogs.com/cleven/p/5255419.html
Copyright © 2011-2022 走看看