您的位置:首页 > 职场人生

黑马程序员——OC基础——category、description和SEL

2015-05-17 08:01 204 查看
-----------android培训java培训、java学习型技术博客、期待与您交流!------------

下面我们学习category,也就是分类的定义和用法。

有时候我们需要在不改变类的模型的前提下给它添加一些方法,我们应该怎么办呢?有两种方式可以实现,那就是继承和分类。继承我们已经学习过了,下面我们来学习什么是分类。

那么分类的格式是什么呢?

分类也需要有类的实现和声明,下面就是分类的声明和实现的格式:

@interface 类名 (分类名称)
//方法声明
@end
@implementation类名 (分类名称)
//方法实现
@end

其中类名就是所要实现分类的类的类名,分类名称就是分类的类名,这里要注意分类名是要用小括号括起来。分类有什么好处呢?分类可以实现团队开发的便利性,也就是说一个类可以有多个人来实现。另外,分类也可以用来对系统自带的类进行扩充。

那么使用分类有哪些注意点呢?

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

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

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

4、类中方法调用的优先级是:分类(最后编译的分类优先级最高)> 原来类 > 父类。

下面我们通过例子来创建Person类的分类:

#import <Foundation/Foundation.h>

// Person类的声明
@interface Person : NSObject
{
NSString *_name;
}
@property NSString *name;
- (void)eat;
@end
// Person类的实现
@implementation Person
- (void)eat
{
NSLog(@"%@在吃饭", _name);
}
@end

// Person分类Run的声明
@interface Person (Run)
- (void)run;
@end
// Person分类Run的实现
@implementation Person (Run)
- (void)run
{
NSLog(@"%@在跑步", _name);
}
@end

int main()
{
Person *p = [[Person alloc] init];
p.name = @"张三";

[p eat];
[p run];

return 0;
}

输出结果是:
张三在吃饭

张三在跑步

下面我们学习description方法。在学习description之前,我们先学习类对象。

什么是类对象呢?其实类就是也是对象,它是Class类型的对象,简称类对象。类名也就是类对象,每个类只有一个类对象。

获取类对象有两种方法,一种是根据类方法来获得,另外一种是根据对象方法来获得。

1、Class c1 = [Person class];  // 根据类方法

2、Person *p = [Person new];

Class c2 = [p class];        // 根据对象方法

description是什么呢?它有两种,一种是类方法,一种是对象方法。

1、使用NSLog和%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出。返回值是:<类名: 对象地址>。

2、使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出。返回值是:类名。

我们可以重写description方法来让对象名和类对象名输出我们想要的结果。比如说:

#import <Foundation/Foundation.h>

// Person类的声明
@interface Person : NSObject
{
NSString *_name;
}
@property NSString *name;
- (void)eat;
@end

// Person类的实现
@implementation Person
- (void)eat
{
NSLog(@"%@在吃饭", _name);
}

// 重写description方法返回我们需要的东西
- (NSString *)description
{
return [NSString stringWithFormat:@"_name = %@", _name];
}
@end

int main()
{
Person *p = [[Person alloc] init];
p.name = @"张三";

NSLog(@"%@", p); // 输出结果是:_name = 张三

return 0;
}

最后我们来学习SEL。SEL其实是对方法的一种包装,它是将方法包装成一个SEL类型的数据,根据这个数据我们可以找到对应的方法地址。SEL也就是消息。下面我们根据SEL来调用对象的方法。

#import <Foundation/Foundation.h>

// Person类的声明
@interface Person : NSObject
@property NSString *name;
- (void)eat;
@end

// Person类的实现
@implementation Person
- (void)eat
{
NSLog(@"%@在吃饭", _name);
}
@end

int main()
{
Person *p = [[Person alloc] init];
p.name = @"张三";

[p performSelector:@selector(eat)]; // 把方法名包装成一个SEL类型的数据并进行调用

return 0;
}


总结:

1、分类中不能定义变量,但是可以调用方法。

2、原来类跟分类同名的方法会被分类的方法覆盖。

3、类中方法调用的优先级是:分类>原来类>父类。

4、类其实是一个Class类型的对象,这个对象可以用来调用类方法,但是不可以调用对象方法。

5、我们可以重写description方法来输出我们想要的东西,这与java中toString方法类似。

6、SEL类型的数据是用来包装方法的,我们可以根据这个数据找到方法的地址并访问这个方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐