• 【非正式协议 Objective-C语言】


    前言

    1.分类的作用在于可以将我们写的类分为多个模块。

    2.可以不可以为系统的类写1个分类呢

    3.为系统自带的类写分类,这个就叫做非正式协议

    一、例如,有下面1个NSObject的分类:

    #import
    @interface NSObject (test)
    – (void)run;
    @end
    #import “NSObject+test.h”
    @implementation NSObject (test)
    – (void)run
    {
    NSLog(@“我piapia的跑。。。”);
    }
    @end

    二、再来1个Person类:

    #import
    @interface Person:NSObject

    @end
    @implementation Person

    @end

    三、main.m文件中如下:

    #import
    #import “NSObject+test.h”
    #import “Person.h”
    int main()
    {
    Person *p1 = [Person new];
    [p1 run];
    }
    这样,p1对象也有了run方法。

    四、为什么Person类有了run方法,因为Person类从NSObject类继承,我们通过分类,是不是为NSObject类加了1个run方法啊。

    #import
    #import “NSObject+test.h”
    #import “Person.h”
    int main()
    {
    Person *p1 = [Person new];
    [p1 run];
    NSString *str = @“jack”;
    [str run];
    }
    这样也是可以的。

    五、分类的第2个作用:为1个已经存在的类添加方法,比如NSObject类加方法,你看不到它的源代码,只能通过分类给它加方法

    例如,你想给NSString类添加一个计算1个字符串内,阿拉伯数字有多少个的方法,怎么办:

    六、NSString类都挺好,就是我觉得差1个方法,统计字符串对象当中有多少个阿拉伯数字

    例如:NSString *str = @“dfjsdij2oroo3or32p324lkltrw346”;
    统计str中有多少个阿拉伯数字:
    思路:遍历字符串当中的每1个字符,如果是[0-9],筐变量++,最后看看筐变量有多少就行了。
    怎么判断每一个字符是不是阿拉伯数字,判断ASCII码吧?
    //思路:
    //遍历字符串中的每1个字符,判断每1个字符是否为阿拉伯数字
    //第1个问题,如何遍历:是不for循环呐
    for(int i = 0 ; i < str.length ; i++)
    {

    }
    //第2个问题,如何取到每1个字符,下标,可以吗,str[i],可以吗,不可以,数组才能用下标,这个不是数组
    //比如现在,我想去取到str这个字符串中,下标为1的那个字符,是不是’f’啊,怎么去取,C语言中怎么去取,是不str[1]啊,记住,这是不行的,因为这是Objective-C,怎么去取呢,你记住,它是对象啊,对象是不是有很多方法啊,[str characterAtIndex:(NSUInteger)]这是可以的,[str characterAtIndex:1]就能拿到这个字符串里面,下标为1的这个字符’f’,拿到什么类型的,是不是char类型的啊,那我用一个char类型的变量去接:
    char ch = [str characterAtIndex:1];
    NSLog(@“ch = %c”,ch);
    输出: ch = f
    那如果 NSString *str = @“中国我爱你beijing”;
    这个时候[str characterAtIndex:1]取得的是什么啊?是不’国’啊?
    输出: ch = y’
    我了个去,怎么是一个乱码呢,这个时候,你[str characterAtIndex:1]拿到的是1个中文字符,这个时候,你char ch = [str characterAtIndex:1];,ch只有1个字符,存不住了,所以,这个方法的返回值是什么啊,是unichar,根本就不是char , - (unichar)characterAtIndex:(NSUInteger)index;所以,需要写成下面这样:
    NSString *str = @“中国我爱你beijing”;
    unichar ch = [str characterAtIndex:1];
    NSLog(@“ch = %c”,ch);
    那unichar又是什么东西呢?
    typedef unsigned short unichar;
    unsigned short占用两个字节;为什么是两个字节呢,原因很简单,因为1个中文的话,1个字节存不下了,1个中文在C语言中,占3个字节,但在Objective-C当中,1个中文占2个字节,汉字有多少个,2万个够不够,1个字节可以存2的8次方减1个,255个汉字,2个字节可以存2的16次方减1个,65535个汉字,所以2个字节足够用,再试一下:
    NSString *str = @“中国我爱你beijing”;
    unichar ch = [str characterAtIndex:1];
    NSLog(@“ch = %c”,ch);
    输出:ch = y`
    怎么还是乱码,因为你用的是"%c"输出,
    %d:它会从ch这个字节开始,连读4个字节,
    %c:它会从ch这个字节开始,连读1个字节,然后再找ASCII码,打印
    %f:
    %s:
    %u:第一个二进制位,不当作符号位,直接当作数据位
    所以,每一个占位符,它的区别,是在内存当中读取的方式不一样,
    所以,我用%c,只不过读了ch这2个字节当中的第1个字节,翻译成ASCII码,可能刚好是y’这个字符,那我现在要读几个字节,是不读2个字节,怎么办,用百分号大C,%C,百分号大C的意思就是,连读2个字节,把它查找ASCII码,翻译回来
    //第3个问题,我们这个循环,要去拿到NSString *str = @“dfjsdij2oroo3or32p324lkltrw346”;里面的每一个字符的话,那就是去调用str的方法:[str characterAtIndex:i];,拿一个unichar变量接一下:
    unichar ch = [ str characterAtIndex:i];
    //这个时候,ch的值,是不是就是我们这个字符串的每1个字符的值啊。
    //第4个问题,判断每1个字符是否为阿拉伯数字,怎么判断:
    if ( ch >= ‘0’ && ch <=‘9’)
    {
    }
    //如果这个条件满足,就说明遍历出来的这个字符是阿拉伯数字吧。
    来个筐变量:int count = 0;
    只要找到阿拉伯数字,框变量就++就可以了吧
    if (ch >= ‘0’ && ch <= ‘9’)
    {
    count++;
    }
    NSLog(@“count = %d”,count);

    七、现在要为NSString 类添加1个number方法,一调这个方法,就能计算出str对象里面有多少个阿拉伯数字。怎么添加,是不用分类添加啊?

    为NSString类添加1个分类:test
    #import
    @interface NSString (test)
    //求当前这个字符串对象中有多少个阿拉伯数字,当前这个对象就是字符串,所以没必要带参数,self就是当前这个字符串了
    – (int)numberCount
    @end
    #import “NSString+test.h”
    @implementation NSString (test)
    ///求当前这个字符串中有多少个阿拉伯数字
    – (int)numberCount
    {
    int count = 0;
    //1.遍历当前字符串对象中的每1个字符
    for(i = 0 ; i < self.length; i++)
    {
    unichar ch = [self characterAtIndex:i];
    if(ch >= ‘0’ && ch <= ‘9’)
    {
    count++;
    }
    }
    return count;
    }

    //然后,在main.m文件中
    #import
    #import “NSString + test.h”
    int main()
    {
    NSString *str = @“fsoifjo3r3049f095ijoerj1324”;
    int count = [str numberCount];
    NSLog(@“%d”,count);
    }

    八、这就是非正式协议,为已经存在的类,也就是为系统的类,为系统自带的类,写分类,这就是非正式协议,所以,分类的作用:1.将臃肿的类分为多个模块,方便管理;2.扩展1个类,你发现有一个类,我想给它加1个方法,怎么加,用分类,这就是分类的两个应用场景。

  • 相关阅读:
    Linux mkdir -p 以及如何创建带有空格的文件夹
    SpringBoot 中到底如何解决跨域问题?
    【Java 基础篇】Java LinkedHashSet 详解:有序唯一元素存储的完美选择
    基于单片机的GPS定位信息显示系统
    Linux 压缩解压(归档管理):tar命令
    【无标题】
    牛客网SQL中等难度
    视野修炼-技术周刊第53期
    jupyter中配置多种虚拟环境
    js将图片或者文件转成base64格式的两种方法
  • 原文地址:https://blog.csdn.net/madoca/article/details/126613813