zoukankan      html  css  js  c++  java
  • objectivec 关于分类的理解

    什么是 objective-c 的分类?

    有的时候,我们需要对原有的类添加一些功能(方法)作为源类扩展,他的功能是扩展类的能力。

    分类需要注意的地方:

    1:尽管分类可以访问原始类的实例变量,但是他不能添加自身的任何变量,如果需要添加变量,可以考虑创建子类。

    2:分类可以重载该类的另一个方法,但是通常认为这种做法是卑劣的设计习惯。第一:重载一个方法后,再也不能访问原来的方法,因此,必须小心将被重载方法中的所有功能复制到替换方法中,如果确实需要重载方法,可以考虑常见子类,如果在子类中重载方法,仍然可以通过想super发送消息类来引用父类的方法。因此不必了解重载方法的内容就能够调用父类的方法,并向子类的方法添加自己的功能。

    3:一个类,可以拥有多个分类

    4:和一般接口不同的是,不必实现分类所有的方法,这个对程序的扩展很有用,因为可以在该类分类的声明所有的方法,然后在一段时间后在来是实现他。

    5:记住,通过分类添加新的方法来扩展该类,不仅仅会影响该类,还会影响该类所有的子类,因此他的所有的子类都会继承这个分类,而不管这些子类愿意不愿意。

    下面给出一段转载的代码,对分类有一个基本的了解

    Link Address:http://archive.cnblogs.com/a/2044073/

    通过分类的方式可以为已存在的类添加新的方法,甚至不需要源码,有点像C#中的扩展方法。

    这时提供一个例子是把一个字符串转换为驼峰式并且出掉单词空格。

    NSString+CamelCase.h

    #import <Foundation/Foundation.h>
     
    //NSString 表示将要添加分类的类名称,该类必须是已存在的。
    //CamelCase 是为类添加的分类的名称。
    //只能添加方法,不能添加变量。
    //头文件命名惯例:ClassName+CategoryName.h
    @interface NSString (CamelCase)
     
    -(NSString*) camelCaseString;
     
    @end

    NSString+CamelCase.m

    #import "NSString+CamelCase.h"
     
    @implementation NSString (CamelCase)
     
    -(NSString*) camelCaseString
    {
        //调用NSString的内部方法获取驼峰字符串。
        //self指向被添加分类的类。
        NSString *castr = [self capitalizedString];
         
        //创建数组来过滤掉空格, 通过分隔符对字符进行组合。
        NSArray *array = [castr componentsSeparatedByCharactersInSet:
                          [NSCharacterSet whitespaceCharacterSet]];
         
        //把数组的字符输出
        NSString *output = @"";
        for(NSString *word in array)
        {
            output = [output stringByAppendingString:word];
        }
         
        return output;
         
    }
     
    @end

    main.m

    #import <Foundation/Foundation.h>
    #import "NSString+CamelCase.h"//添加该类
     
    int main (int argc, const char * argv[])
    {
     
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     
        NSString *str = @"My name is bill.";
        NSLog(@"%@", str);
        str = [str camelCaseString];
        NSLog(@"%@", str);
     
        [pool drain];
        return 0;
    }
    e
    下面是另外一个例子,可以很好的解释分类的用处:
    student.m

    #import <Foundation/Foundation.h>

     

    @interface student : NSObject 

    {

    NSString *Name;

    }

    -(void)setName:(NSString *)_name;

    -(NSString *)Name;

    -(void)printValue;

    @end

    studeng.m

    #import "student.h"

    #import <Foundation/Foundation.h>

     

    @implementation student

    -(void)setName:(NSString *)_name

    {

    Name = _name;

    }

     

    -(NSString *)Name

    {

    return Name;

    }

     

    -(void)printValue

    {

    NSLog(self.Name,nil);

    }

    @end

    studentExt.h

     

    #import <Foundation/Foundation.h>

    #import "student.h"

     

    @interface student (extSt)

     

    -(void)printValueExt;

    -(void)printValue;

     

    @end

    studentExt.m

     

    #import "studentExt.h"

     

     

    @implementation student (extSt)

     

    -(void)printValueExt

    {

    NSLog(@"这个是类扩展后添加的方法!");

    }

     

    -(void)printValue

    {

    NSLog(@"这个是重载后的函数的处理的结果!");

    }

     

    @end

     下面的调用的函数

    #import <Foundation/Foundation.h>

    #import "student.h"

    #import "studentExt.h"

    int main (int argc, const char * argv[]) 

    {

        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    /////////////////////

    student *stu = [[[student alloc] init] autorelease];

    [stu setName:@"this is orign NameStr"];

    [stu printValue];

    [stu printValueExt];

    /////////////////////

    [pool drain];

        return 0;

    }

    上面的代码基本上说明了,分类的作用,你懂的哦。。
    总结:
    关于分类,我感觉使用在扩展那些你无法看到类的实现代码的类的,你可以为这些类添加扩展函数,可以重载源类中的成员函数,来满足自己的实际需求,但是对于那些你可以看到类的实现、访问的类来说,你则完全没有必要写分类。另外对于那些需要分工合作的工作,也是适合写分类的地方。
    另外一点也是需要注意的是:
    如果你用分类的方式重载了Cocoa类,那么你的App就有可能同不过苹果的作品审核,因为苹果对这些自定义的修改的要求是极其严格,甚至说是苛刻的。
    因此,不建议使用objective-c语言的分类。
    THE END !
  • 相关阅读:
    Docker-CentOS系统安装Docker
    Docker-准备Docker环境
    Docker系列-文章汇总
    商品订单库存一致性问题的思考
    java模板、工厂设计模式在项目中的重构
    2018Java年底总结
    java的AQS中enp没有同步代码块为啥是原子操作
    java使用awt包在生产环境docker部署时出现中文乱码的处理
    初探装饰器模式
    开灯问题
  • 原文地址:https://www.cnblogs.com/xingchen/p/2101820.html
Copyright © 2011-2022 走看看