Extension与Category

  • 转自:Minutia on Objective-C Categories and Extensions

    Objective-C 2.0增加了class extensions用于解决两个问题:

    1. 允许一个对象可以拥有一个私有的interface,且可由编译器验证。
    2. 支持一个公有只读,私有可写的属性。

    私有接口(Private Interface)

    Objective-C 2.0以前, 若要定义私有函数,通常是在实现文件中声明一个"Private" category:

    @interface MyClass (Private) 

     - (id)awesomePrivateMethod; 

    @end

    然而, 类的私用方法通常是希望实现在类的@implementation块中的,而不是像上面的Category的方法那样实现在独立的@implementation区块中。事实上,Category仅仅是弥补了Objective-C缺少public/private限定的不足。

     

    真正的问题是Objective-C编译器会认为在Category中声明的方法将会在别处实现,所以编译器并不会尝试确认它们是不是真得都被实现了。也就是说,开发者声明的方法有可能并未实现,而且编译器也不会有什么警告。编译会以为它们将在别的地方或独立的文件中实现。

     

    使用class exteionsion,在其中声明的方法和属性的实现将放在class的@implementation区块中。否则,编译器就会报错。

    [cpp] view plaincopyprint?

    1. // someClass.m   
    1. @interface someClass ()   
    2. -(void)extend;   
    3. @end   
    4.    
    5. @implementation someClass   
    1. // 所有声明在头文件或父类中方法的实现   
    2. // 或者一些私有函数   
    1. -(void)extend {   
    2.     // implement private method here;   
    1. }   
    2.    
    1. @end  

     

    公有可读、私有可写的属性(Publicly-Readable, Privately-Writeable Properties)

    实现一个不可变(immutable)的数据结构通常有一个好处是外部代码不能用setter修改对象的状态。然而,可能又希望它在内部又是一个可写的属性。Class extensions可以做到这一点:在公共接口(类的声明中)中,开发者可以声明一个属性是只读的,随后在类扩展中声明为可写。这样,对外部代码而言,该属性将是只读的,而内部代码却可以使用它setter方法。

     

    [cpp] view plaincopyprint?

    1. @interface MyClass : NSObject  
    2. @property (retain, readonly) float value;  
    1. @end  
    1.    
    1. // 私有的extension, 隐藏在主实现文件中.  
    1. @interface MyClass ()  
    1. @property (retain, readwrite) float value;  
    1. @end  

     

    看起来相似,其实不同

    Class extension常常被误解为一个匿名的category。它们的语法的确很相似。虽然都可以用来为一个现有的类添加方法和属性,但它们的目的和行为却是不同的。

     

    参考: Apple Documenation

    原文地址: Minutia on Objective-C Categories and Extensions

    转载请注明出处: http://blog.csdn.net/horkychen

     

    @interface部分

     

    @interfaceNSString (category_name)

    //method //方法声明

    @end

     

    @impelementation部分

     

    @impelementation

    //methodimpelementation

    @end

     

    类别中不能添加实例变量,可以添加属性,且属性必须为@dynamic类型的。

    当类别中方法与现有方法(当前类中)重名时,类别的方法具有更高的优先级。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值