IOS面试题(1)----分类

来源:互联网 发布:诗经楚辞取名 知乎 编辑:程序博客网 时间:2024/04/28 13:41

1.你有没有用到过分类?怎么用?
类别(category)是Objective-C的一项功能,可扩展类的接口,而无需对类进行子类化,我们可以在不知道某个类内部实现的情况下,为该类增加方法。如果我们想增加某个框架(framework)中的类的方法,category 就非常有效。类别并不能为类声明新的实例变量,他只包含方法。然而在类作用域内所有实例变量,都能被这些类别访问。他们包括为类声明的所有的实例变量,甚至那些被@private 修饰的变量。可以为一个类添加多个类别,但每个类别名必须不同,而且每个类别都必须声明并实现一套不同的方法。
我们通过 category 来修改一个类的时候,他对应用程序里这个类所有对象都起作用。跟子类不一样,category 不能增加成员变量。我们还可以用 category里重写类原先存在的方法(但是并不推荐这么做)。
可以将类别作为一种手段,对头文件中的相关方法声明进行分组,甚至还可以将不同的类别声明放在不同的头文件中,框架在其所有的头文件中使用这些技巧达到清晰明确的效果,还可以使用称为类别扩展的匿名类别,在实现文件(.m)文件中声明专有的属性和专有的方法。

类别主要有3个作用:


(1)将类的实现分散到多个不同文件或多个不同框架中。



(2)创建对私有方法的前向引用。




(3)向对象添加非正式协议。
 继承可以增加,修改或者删除方法,并且可以增加属性。
下面是经常用的一个Category。

//UIView+Extension.h#import <UIKit/UIKit.h>@interface UIView (Extension)//括号中的是分类的名字@property (nonatomic, assign) CGFloat x;@property (nonatomic, assign) CGFloat y;@property (nonatomic, assign) CGFloat maxX;@property (nonatomic, assign) CGFloat maxY;@property (nonatomic, assign) CGFloat centerX;@property (nonatomic, assign) CGFloat centerY;@property (nonatomic, assign) CGFloat width;@property (nonatomic, assign) CGFloat height;@property (nonatomic, assign) CGSize size;@end//UIView+Extension.m#import "UIView+Extension.h"@implementation UIView (Extension)- (void)setX:(CGFloat)x{    CGRect frame = self.frame;    frame.origin.x = x;    self.frame = frame;}- (CGFloat)x{    return self.frame.origin.x;}- (void)setMaxX:(CGFloat)maxX{    self.x = maxX - self.width;}- (CGFloat)maxX{    return CGRectGetMaxX(self.frame);}- (void)setMaxY:(CGFloat)maxY{    self.y = maxY - self.height;}- (CGFloat)maxY{    return CGRectGetMaxY(self.frame);}- (void)setY:(CGFloat)y{    CGRect frame = self.frame;    frame.origin.y = y;    self.frame = frame;}- (CGFloat)y{    return self.frame.origin.y;}- (void)setCenterX:(CGFloat)centerX{    CGPoint center = self.center;    center.x = centerX;    self.center = center;}- (CGFloat)centerX{    return self.center.x;}- (void)setCenterY:(CGFloat)centerY{    CGPoint center = self.center;    center.y = centerY;    self.center = center;}- (CGFloat)centerY{    return self.center.y;}- (void)setWidth:(CGFloat)width{    CGRect frame = self.frame;    frame.size.width = width;    self.frame = frame;}- (CGFloat)width{    return self.frame.size.width;}- (void)setHeight:(CGFloat)height{    CGRect frame = self.frame;    frame.size.height = height;    self.frame = frame;}- (CGFloat)height{    return self.frame.size.height;}- (void)setSize:(CGSize)size{    CGRect frame = self.frame;    frame.size = size;    self.frame = frame;}- (CGSize)size{    return self.frame.size;}@end

延展(Extension)是“匿名”的类目,延展定义类的私有方法,一般是在类的实现文件@implementation之上定义如:Person() 和类目的区别在于括号里面是空的,没有名字的,暂时性的存在,只能本类调用方法,子类也无法调用父类的延展

另外在本类的实现文件@implementation之上也可以定义私有方法,私有的静态变量

延展的特点就是定义私有方法

// extension@interface MyObject(){    int iextension;}-(void)testInExtension;// 类的mainimplementation不实现的话,有编译警告。@end// category@interface  MyObject(categoryDemo){    //   int icategory;   // error: Ivarsmay not be placed in categories}-(void)testInCategory;// 不强制要求在类的mainimplementation中实现@end

他们的主要区别是:

1、形式上来看,extension可以认为是私有的category。
2、extension里声明的方法需要在mainimplementation中实现,category不强制要求。
3、extension可以添加属性(变量),category不可以。

2说一说协议?
协议(Protocol)
没有父类也不能定义实例变量,只声明方法,声明未知类的接口,两个类之间的通信
@required :必须实现。默认
@optional :选择性的实现
NSObject为基本类根类也为基协议,可以写也可以不写。
因为IOS中不可以多继承,所以可以通过Protocol委托代理,实现多个接口来实现多继承。
委托(Delegate)
delegate中文叫做委托,通常会用在class内部把一些事件处理”委托”给别人去完成。
Delegate本身应该称为一种设计模式,是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成,而实际做事的类为delegate。而protocol是一种语法,它的主要目标是提供接口给遵守协议的类使用,而这种方式提供了一个很方便的、实现delegate模式的机会。
用法如下

// 数据源方法@protocol SLWaterFlowViewDataSource <NSObject>@required//  一共有多少个数据- (NSUInteger)numberOfCellsInWaterFlowView:(SLWaterFlowView *)waterFlowView;// 返回index位置对应的cell- (SLWaterFlowViewCell *)waterFlowView:(SLWaterFlowView *)waterFlowView cellAtIndex:(NSUInteger)index;@optional// 一共有多少列- (NSUInteger)numberOfColumnsInWaterFlowView:(SLWaterFlowView *)waterFlowView;@end// 代理方法@protocol SLWaterFlowViewDelegate <UIScrollViewDelegate>@optional//  第index位置cell对应的高度- (CGFloat)waterFlowView:(SLWaterFlowView *)waterFlowView heightAtIndex:(NSUInteger)index;// 选中第index位置的cell- (void)waterFlowView:(SLWaterFlowView *)waterFlowView didSelectAtIndex:(NSUInteger)index;// 返回间距- (CGFloat)waterFlowView:(SLWaterFlowView *)waterFlowView marginForType:(SLWaterFlowViewMarginType)type;@end
0 0
原创粉丝点击