第一讲 数组

2018-11-21  本文已影响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,]
上一篇 下一篇

猜你喜欢

热点阅读