美文网首页
第一讲 数组

第一讲 数组

作者: 飞奔的小鲨鱼 | 来源:发表于2018-11-21 23:13 被阅读0次

数组在我们日常的开发工作中可以说是最常见的了,但是今天我们不讲数组这么使用,我们说一说面向对象编程方式下数组的使用。

1. 使用自定义类封装数组

我们创建一个XSYArray的类,并且提供它的一些初始化方法。

@interface XSYArray : NSObject<NSCopying, NSMutableCopying>
// 数组的长度
@property (nonatomic, assign, readonly) NSInteger length;
+ (instancetype)array;
+ (instancetype)xsy_arrayWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)xsy_arrayWithArray:(NSArray *)array;
- (instancetype)xsy_initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)xsy_initWithArray:(NSArray*)array;

XSYArray.m文件中对应的方法实现:

@interface XSYArray ()
@property (nonatomic, strong) NSMutableArray * data;
@end
@implementation XSYArray
+ (instancetype)array{
    return [[self alloc] xsy_initWithArray:@[]];
}
+ (instancetype)xsy_arrayWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION{
    va_list argList;
    NSMutableArray * temp = [NSMutableArray array];
    if (firstObj) {
        [temp addObject:firstObj];
        va_start(argList, firstObj);
        id obj;
        while ((obj = va_arg(argList, id))) {
            [temp addObject:obj];
        }
    }
    va_end(argList);
    return [[self alloc] xsy_initWithArray:temp];
}
+ (instancetype)xsy_arrayWithArray:(NSArray *)array{
    return [[self alloc] xsy_initWithArray:array];
}
- (instancetype)xsy_initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION{
    //VA_LIST 是在C语言中解决变参问题的一组宏
    va_list argList;
    if (firstObj) {
        [self.data addObject:firstObj];
        // VA_START宏,获取可变参数列表的第一个参数的地址,在这里指向firstObj
        va_start(argList, firstObj);
        // 临时指针变量
        id obj;
        // VA_ARG宏,获取当前可变参数,返回指定类型并将指针指向下一参数
        // 首先 argList的内存地址指向的fristObj将对应储存的值取出,放在数组中,
        // 并且将指针指向下一个参数,这样每次循环指针偏移量就不断下移直到取出nil
        while ((obj = va_arg(argList, id))) {
            [self.data addObject:obj];
        }
    }
    // 清空列表
    va_end(argList);
    return [self init];
}
- (instancetype)xsy_initWithArray:(NSArray*)array{
    _data = [NSMutableArray arrayWithArray:array];
    return [self init];
}

- (instancetype)init{
    if (self == [super init]) {
       
    }
    return self;
}

- (NSMutableArray *)data{
    if (!_data) {
        _data = [NSMutableArray array];
    }
    return _data;
}

- (NSInteger)length{
    return self.data.count;
}

- (NSString *)description{
    NSMutableString * mString = [NSMutableString stringWithString:@"["];
    for (id obj in self.data) {
        [mString appendString:[NSString stringWithFormat:@" %@,",obj]];
    }
    [mString appendString:@"]"];
    return mString;
}

#pragma mark - NSCopying
- (id)copyWithZone:(nullable NSZone *)zone{
    XSYArray * arr = [self.class new];
    arr.data = _data;
    return arr;
}

#pragma mark - NSMutableCopying
- (id)mutableCopyWithZone:(nullable NSZone *)zone{
    return [self copyWithZone:zone];
}

这样通过这些方法我们就可以创建出一个XSYArray对象类

2. 添加方法来实现数据操作

下面我们为这个XSYArray类添加一些增,删,改,查的方法

- (void)xsy_insertWithObject:(id)obj;
- (void)xsy_removeWithObject:(id)obj;
- (NSInteger)xsy_searchWithObject:(id)obj;
- (void)xsy_updateWithObject:(id)obj index:(NSInteger)idx;
- (NSArray *)xsy_allObjects;
- (void)xsy_removeAllObjects;
- (id)xsy_objectWithIndex:(NSInteger)idx;
- (void)xsy_enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL * stop))block;

XSYArray.m中对应的方法实现:

- (void)xsy_insertWithObject:(id)obj{
    if (obj) {
        [self.data addObject:obj];
    }
    else{
        NSLog(@"insert object nil");
    }
}

- (void)xsy_removeWithObject:(id)obj{
    if (obj && [self.data containsObject:obj]) {
        [self.data removeObject:obj];
        NSLog(@"delete %@ success!",obj);
    }
    else{
        NSLog(@"This %@ is not exist!",obj);
    }
}

-(NSInteger)xsy_searchWithObject:(id)obj{
    NSInteger idx = -1;
    if (obj && [self.data containsObject:obj]) {
       idx = [self.data indexOfObject:obj];
    }
    else{
        NSLog(@"This %@ is not exist!",obj);
    }
    return idx;
}

- (void)xsy_updateWithObject:(id)obj index:(NSInteger)idx{
    if (obj && (idx >= 0 && idx < self.data.count)) {
        [self.data replaceObjectAtIndex:idx withObject:obj];
    }
    
}

- (NSArray *)xsy_allObjects{
    return self.data;
}

- (void)xsy_removeAllObjects{
    [self.data removeAllObjects];
}

- (id)xsy_objectWithIndex:(NSInteger)idx{
    if (idx >= 0 && idx < self.data.count) {
        return [self.data objectAtIndex:idx];
    }
    return nil;
}

- (void)xsy_enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL * stop))block{
    NSMutableArray * temp = self.data;
    [temp enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (block) {
            block(obj,idx,stop);
        }
    }];
}

数组中最常见的应该就是插入为nil而引发的奔溃问题:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil',通过对系统方法的封装,从而达到解决奔溃的问题。

下面我们测试一下这个类的使用:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    XSYArray * array0 = [XSYArray array];
    [array0 xsy_insertWithObject:@"a"];
    [array0 xsy_insertWithObject:@"b"];
    [array0 xsy_insertWithObject:@"c"];
    NSLog(@"array0 ---- %@",array0);
    [array0 xsy_removeWithObject:@"d"];
    [array0 xsy_updateWithObject:@"d" index:2];
    id obj = nil;
    [array0 xsy_insertWithObject:obj];
    NSInteger idx1 = [array0 xsy_searchWithObject:@"1"];
    NSInteger idx2 = [array0 xsy_searchWithObject:@"b"];
    NSLog(@"array0 ---- %@ , %ld , %ld",array0,idx1,idx2);
    
    XSYArray * array1 = [[XSYArray alloc] xsy_initWithObjects:@"1",@"2",@"3",@"4",nil];
    NSLog(@"array1 ----- %@",array1);
    
    [array1 xsy_enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ([obj isEqualToString:@"3"]) {
            *stop = YES;
        }
        NSLog(@"array1 --- obj %@, idx %ld , stop %p",obj,idx,stop);
    }];
    
    XSYArray * array3 = [array0 copy];
    NSLog(@"array1 ----- %@ ,array3 ----- %@",array1,array3);
    [array1 xsy_removeAllObjects];
    NSLog(@"array1 ----- %@ ,array3 ----- %@",array1,array3);
}

打印结果:

array0 ---- [ a, b, c,]
This d is not exist!
insert object nil
This 1 is not exist!
array0 ---- [ a, b, d,] , -1 , 1
array1 ----- [ 1, 2, 3, 4,]
array1 --- obj 1, idx 0 , stop 0x7fff51b7099f
array1 --- obj 2, idx 1 , stop 0x7fff51b7099f
array1 --- obj 3, idx 2 , stop 0x7fff51b7099f
array1 ----- [ 1, 2, 3, 4,] ,array3 ----- [ a, b, d,]
array1 ----- [] ,array3 ----- [ a, b, d,]

相关文章

  • 第一讲 数组

    数组在我们日常的开发工作中可以说是最常见的了,但是今天我们不讲数组这么使用,我们说一说面向对象编程方式下数组的使用...

  • 线性结构初探:数组,线性表

    目录: 1.数组特性 2.数组与线性表的关系 数组特性: 今天我们来讲一讲线性结构,计算机中,数组应该是最常见的数...

  • 看得见的数据结构Android版之表的数组实现(数据结构篇)

    零、前言: 一讲到装东西的容器,你可能习惯于使用ArrayList和数组,你有想过ArrayList和数组的区别吗...

  • 二十一讲 数组2 读取

    VBA数组 1.在内存中读取 在内存中读取后用于继续运算,直接用下面的格式。表示编号是5的数字,并不是行数。如编号...

  • 4.1.3如何使用数组

    使用数组需要按以下4个步骤进行第1步声明数组。例如int[]=a第2步分配数组内存空间,例如a= new int[...

  • LeetCode热门100题算法和思路(day7)

    LeetCode215 数组中的第k个最大元素 题目详情 给定整数数组 nums 和整数 k,请返回数组中第 k ...

  • Day76 数组中的第K个最大元素

    Day76 数组中的第K个最大元素 在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 ...

  • LeetCode-215-数组中的第K个最大元素

    数组中的第K个最大元素 题目描述:给定整数数组 nums 和整数 k,请返回数组中第 **k** 个最大的元素。请...

  • 第 13 章 数组类

    第 13 章 数组类 13.1 复习数组 数组是带索引的对象的集合。 13.2 数组的创建方法 使用 [] 创建数...

  • 第四天 数组【悟空教程】

    第四天 数组【悟空教程】 第04天 Java基础 第1章数组 1.1数组概念 软件的基本功能是处理数据,而在处理数...

网友评论

      本文标题:第一讲 数组

      本文链接:https://www.haomeiwen.com/subject/cikcqqtx.html