黑马程序员——OC---OC特有语法02

本文详细介绍了Objective-C中的分类机制,包括其用途、语法及注意事项,并通过实例展示了如何给NSString类添加新方法。此外,还探讨了类的本质、description方法的重写以及SEL的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Class c = [Person class];
Person *p2 = [c new];

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一 分类

1 什么分类?

有的时候,我们需要对原有的类添加一些功能(方法)作为源类扩展,他的功能是扩展类的能力。这种情况下,OC提供了一种完成上述扩展的机制,就是分类。

使用分类,一个庞大的类可以分模块开发,也可以由多个人来编写,更有利于团队合作。

2 分类的语法

@interface 类名 (分类名称)

// 方法声明

@end

Ø   分类的实现

@implementation类名 (分类名称)

// 方法实现

@end

3 分类使用的注意事项

1>Category可以访问原始类的实例变量,但不能添加变量,只能添加方法。如果想添加变量,可以考虑通过继承创建子类

2>Category可以实现原始类的方法,但不推荐这么做,因为它是直接替换掉原来的方法,这么做的后果是再也不能访问原来的方法

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

4>多个Category中如果实现了相同的方法,只有最后一个参与编译的才会有效

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

下面代码实现给NSString增加一个类方法:计算某个字符串中阿拉伯数字的个数和给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数的工能:

//  NSString+Number.h

#import <Foundation/Foundation.h>

@interface NSString (Number)

+ (int)numberCountOfString:(NSString *)str;

- (int)numberCount;

@end

#import "NSString+Number.h"

@implementation NSString (Number)

+ (int)numberCountOfString:(NSString *)str
{
    // 1.定义变量计算数字的个数
//    int count = 0;
//    
//    for (int i = 0; i<str.length; i++)
//    {
//        unichar c = [str characterAtIndex:i];
//        
//        if ( c>='0' && c<='9')
//        {
//            count++;
//        }
//    }
//    return count;
    
    return [str numberCount];
}

- (int)numberCount
{
    int count = 0;
    
    for (int i = 0; i<self.length; i++)
    {
        // 取出i这个位置对应的字符
        unichar c = [self characterAtIndex:i];
        
        // 如果这个字符是阿拉伯数字
        if ( c>='0' && c<='9' )
        {
            count++;
        }
    }
    
    return count;
}

@end
二 类的本质

类也是一个对象,是Class类型的对象,简称“类对象”,类名就代表着类对象,每个类只有一个类对象。Class类型的定义如下

typedef struct objc_class *Class;

+load方法和+initialize方法

在程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法。因为先加载父类,再加载子类,也就是先调用父类的+load,再调用子类的+load;先加载原始类,再加载分类。并且不管程序运行过程有没有用到这个类,都会调用+load加载。

在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法,一个类只会调用一次+initialize方法,先调用父类的,再调用子类的。

我们可以有一下两种方式获取类对象:

Class c = [Person class]; // 类方法
//另一种方式
Person *p = [Person new];
Class c2 = [p class]; // 对象方法
通过一下方式进行类对象的调用:
Class c = [Person class];
Person *p2 = [c new];

三 description方法

默认情况下,利用NSLog和%@输出对象时,结果是:<类名:内存地址>,这是因为当使用NSLog和%@时自动会调用对象p的-description方法,拿到-description方法的返回值(NSString *)显示到屏幕上而,-description方法默认返回的是“类名+内存地址”。所以我们可以重写-description或者+description方法达到修改NSLog的默认输出的目的。

特别注意的是,如果在-description方法中使用NSLog打印self,会出现死循环。

下面代码是对description方法进行重写的一个实例:

#import "Person.h"

@implementation Person

- (NSString *)description
{

   return [NSString stringWithFormat:@"age=%d, name=%@", _age, _name];
}

// 决定了类对象的输出结果
+ (NSString *)description
{
    return @"Abc";
}

@end
四 SEL

SEL是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。也就是说SEL可以代替方法,每个方法有方法名,ID,地址,相同的方法名,ID也一样,正常情况下我们根据方法名找到方法,用SEL方法可以根据ID找到方法。
SEL对象的创建如下方式

SEL s = @selector(test);
SEL s2 = NSSelectorFromString(@"test");
SEL对象的其他用法

// 将SEL对象转为NSString对象
NSString *str = NSStringFromSelector(@selector(test));

Person *p = [Person new];
// 调用对象p的test方法
[p performSelector:@selector(test)];
五 关于NSLog输出

1  __FILE__ :源代码文件名

2  __LINE__ :NSLog代码在第几行

3  _cmd :代表着当前方法的SEL

注意,如下代码会引发死循环

- (void)test {
    [self performSelector:_cmd];
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值