Cowboy Tech

iOS设计模式-迭代器

线性表

  1. 定义:线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的
  2. 种类:链表,栈,队列

单链表

Node

@interface Node : NSObject
//指向下一个节点
@property (nonatomic, strong) Node  *nextNode;
//节点挂载的对象
@property (nonatomic, strong) id     item;
//便利构造器
+ (instancetype)nodeWithItem:(id)item;
@end
---------------------------------------------------
@implementation Node

+ (instancetype)nodeWithItem:(id)item {

Node *node = [[[self class] alloc] init];
node.item  = item;

return node;
}

@end

LinkedList

@interface LinkedList : NSObject

//头节点
@property (nonatomic, strong, readonly) Node *headNode;

//有几个节点

@property (nonatomic, readonly) NSInteger  numberOfNodes;

//节点挂载的对象
- (void)addItem:(id)item;

@end
----------------------------------------------------------

@interface LinkedList ()

@property (nonatomic, strong) Node       *headNode;
@property (nonatomic)         NSInteger   numberOfNodes;

@end

@implementation LinkedList

- (void)addItem:(id)item {

if (self.headNode == nil) {

    // 创建头结点
    self.headNode = [Node nodeWithItem:item];

} else {

    [self addItem:item node:self.headNode];
}

self.numberOfNodes++;
}

#pragma mark - 私有方法
- (void)addItem:(id)item node:(Node *)node {

if (node.nextNode == nil) {

    node.nextNode = [Node nodeWithItem:item];

} else {

    [self addItem:item node:node.nextNode];
}
}

@end

系统迭代器: NSEnumerator

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

// 创建集合对象, 可以是数组,字典,集合等..
NSArray *datas = @[@"A", @"B", @"C", @"D"];

// 从集合对象创建迭代器
NSEnumerator *iterator = [datas objectEnumerator];

// 从集合对象中访问元素, 头元素已经实现了空实现
id arrayObj = nil;
while (arrayObj = [iterator nextObject]) {
    NSLog(@"%@", arrayObj);
}

迭代器模式

LinkedList:头元素必须已经实现了空实现

- (instancetype)init{

self = [super init];
if (self) {

    self.headNode = [Node new];
}

return self;
}

IteratorProtocol

@protocol IteratorProtocol <NSObject>

@required
//下一个对象
- (id)nextObject;
@end

LinkedListIterator

@interface LinkedListIterator : NSObject <IteratorProtocol>
+ (instancetype)linkedListIteratorWithLinkedList:(LinkedList *)linkedList;

@end

@interface LinkedListIterator ()

@property (nonatomic, strong) LinkedList *linkedList;
@property (nonatomic, strong) Node       *currentNode;

@end

@implementation LinkedListIterator

+ (instancetype)linkedListIteratorWithLinkedList:(LinkedList *)linkedList {

LinkedListIterator *linkedListIterator = [LinkedListIterator new];
linkedListIterator.linkedList  = linkedList;
linkedListIterator.currentNode = linkedList.headNode;    
return linkedListIterator;
}

- (id)nextObject {
self.currentNode = self.currentNode.nextNode;
return self.currentNode;
}

@end

ViewController

@interface ViewController ()
@property (nonatomic, strong) LinkedList *list;
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// 创建集合对象
self.list = [[LinkedList alloc] init];
[self.list addItem:@"A"];
[self.list addItem:@"B"];
[self.list addItem:@"C"];
[self.list addItem:@"D"];

// 从集合对象创建迭代器
LinkedListIterator *linkedIterator = [LinkedListIterator linkedListIteratorWithLinkedList:self.list];

// 从集合对象中访问元素
Node *node = nil;
while (node = [linkedIterator nextObject]) {    
    NSLog(@"%@", node.item);
}

}
@end

实现组合对象的迭代器

Node

@interface Node : NSObject
@property (nonatomic, strong) Node  *nextNode;

//节点挂载的对象, 注意这里是weak,因为customView已经持有那些对象了
@property (nonatomic, weak)   id     item;

+ (instancetype)nodeWithItem:(id)item;
@end

--------------------------------------------

@implementation Node

+ (instancetype)nodeWithItem:(id)item {

    Node *node = [[[self class] alloc] init];
    node.item  = item;

    return node;
}

@end

LinkedList

@interface LinkedList : NSObject
@property (nonatomic, strong, readonly) Node *headNode;
@property (nonatomic, readonly) NSInteger  numberOfNodes;
- (void)addItem:(id)item;
@end

@interface LinkedList ()
@property (nonatomic, strong) Node       *headNode;
@property (nonatomic)         NSInteger   numberOfNodes;
@end

@implementation LinkedList

- (instancetype)init{

self = [super init];
if (self) {

    self.headNode = [Node new];
}

return self;
}

- (void)addItem:(id)item {

if (self.headNode == nil) {

    // 创建头结点
    self.headNode = [Node nodeWithItem:item];

} else {

    [self addItem:item node:self.headNode];
}

self.numberOfNodes++;
}

#pragma mark - 私有方法
- (void)addItem:(id)item node:(Node *)node {

if (node.nextNode == nil) {

    node.nextNode = [Node nodeWithItem:item];

} else {

    [self addItem:item node:node.nextNode];
}
}

@end

IteratorProtocol

@protocol IteratorProtocol <NSObject>

- (id)nextObject;
- (void)resetIterator;
@end

CustomView

@interface CustomView : UIView <IteratorProtocol>

@end

@interface CustomView ()
@property (nonatomic, strong) UIButton    *button;
@property (nonatomic, strong) UILabel     *label;
@property (nonatomic, strong) UITextField *field;
@property (nonatomic, strong) LinkedList  *list;
@property (nonatomic, strong) Node        *currentNode;

@end

@implementation CustomView

- (instancetype)initWithFrame:(CGRect)frame{

    self = [super initWithFrame:frame];
    if (self) {

        self.button = [[UIButton alloc] initWithFrame:self.bounds];
        self.label  = [[UILabel alloc] initWithFrame:self.bounds];
        self.field  = [[UITextField alloc] initWithFrame:self.bounds];

        [self addSubview:self.button];
        [self addSubview:self.label];
        [self addSubview:self.field];

        self.list = [[LinkedList alloc] init];
        [self.list addItem:self.button];
        [self.list addItem:self.label];
        [self.list addItem:self.field];

        self.currentNode = self.list.headNode;
    }

    return self;
}

- (id)nextObject {

    self.currentNode = self.currentNode.nextNode;
    return self.currentNode;
}

- (void)resetIterator {

    self.currentNode = self.list.headNode;
}

@end

ViewController

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

CustomView *customView = [[CustomView alloc] initWithFrame:self.view.bounds];

Node *node = nil;

[customView resetIterator];
while (node = [customView nextObject]) {

    NSLog(@"%@", node.item);
}

[customView resetIterator];
while (node = [customView nextObject]) {

    NSLog(@"%@", node.item);
}

}
@end

最小知识原则

让使用者不用了解过多的细节,暴露在.h的文件越少越好,如果可以写在.m里最好

迭代器筛选

[customView resetIterator];
while (node = [customView nextObject]) {

    NSLog(@"%@", node.item);

    if ([node.item isKindOfClass:[UIButton class]]){

    }
}