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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值