关于数组内元素是否会被改变的思考

起因

项目中双层for循环时,想当然的认为内部局部指针变量的变化会影响外面数组中模型的地址。结果调试后发现,是不对的。

- (void)pmy_updateCachedArr:(NSArray<HTBNWaitBusesM4Cal *> *)cachedArr     withNewInfoArr:(NSArray<HTBNWaitBusesM4Cal *> *)newInfoArr{
    [newInfoArr enumerateObjectsUsingBlock:^(HTBNWaitBusesM4Cal * _Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop) {
        for (int i = 0; i < cachedArr.count; ++i) {
            HTBNWaitBusesM4Cal *lM = cachedArr[i];
            if ([lM isEqual:obj]) {
                
                //不能这么做,lM地址会变,但是无法影响for循环外面数组中元素的地址!!!思考作用域原理即可理解。
//                lM = obj;

//外面数组中元素的属性是可以被改变的
                lM.gNearestStaM = obj.gNearestStaM;
            }
        }
    }];
}

结论

  • 不同的循环语法不影响结果
  • 数组是否可变不影响结果
  • 想改变数组中模型的地址,必须用系统方法!模型的属性可以被改变
  • 想想变量赋值原理和作用域的概念,可能会豁然开朗

测试代码


#import "ViewController.h"
#import "Person.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self test1];
    [self test2];
    [self test3];
    //[self test4];
    //[self test5];
}

- (void)test1{
    Person *lP1 = [[Person alloc] init];
    lP1.gStr4Name = @"1号";
    
    Person *lP2 = [[Person alloc] init];
    lP2.gStr4Name = @"2号";
    
    lP1 = lP2;
    NSLog(@"%@,%@",lP1,lP2);
    NSLog(@"test1 lP1.gStr4Name:%@",lP1.gStr4Name);
}

- (void)test2{
    Person *lP1 = [[Person alloc] init];
    lP1.gStr4Name = @"1号";
    
    Person *lP2 = [[Person alloc] init];
    lP2.gStr4Name = @"2号";
    
    NSArray *lArr1 = @[lP1];
    NSArray *lArr2 = @[lP2];
    [lArr1 enumerateObjectsUsingBlock:^(Person *  _Nonnull obj,BOOL * _Nonnull stop) {
        for (int i = 0; i < lArr2.count; ++i) {
            Person *lP2 = lArr2.lastObject;
            obj = lP2;
        }
    }];
    
    Person *lP = lArr1.firstObject;
    NSLog(@"%@,lP2);
    
    //原以为会打印 2号,想想变量赋值原理和作用域的概念,豁然开朗
    NSLog(@"test2 lP.gStr4Name:%@",lP.gStr4Name);
}

- (void)test3{
    Person *lP1 = [[Person alloc] init];
    lP1.gStr4Name = @"1号";
     NSLog(@"1  P1:%@",lP1);
    Person *lP2 = [[Person alloc] init];
    lP2.gStr4Name = @"2号";
     NSLog(@"1  P2:%@",lP2);
    
    NSArray *lArr1 = @[lP1];
    NSArray *lArr2 = @[lP2];
    
    //不同的循环语法不影响结果
    for (int i = 0; i < lArr1.count; ++i) {
        Person *lP1 = lArr1.firstObject;
         NSLog(@"2  P1:%@",lP1);
        for (int j = 0; j < lArr2.count; ++j) {
            Person *lP2 = lArr2.lastObject;
            lP1 = lP2;
            NSLog(@"2 P2:%@",lP2);
        }
         NSLog(@"3  P1:%@",lP1);
    }
    
    Person *lP = lArr1.firstObject;
    NSLog(@"4:%@,lP2);
    NSLog(@"test3 lP.gStr4Name:%@",lP.gStr4Name);
}

- (void)test4{
    Person *lP1 = [[Person alloc] init];
    lP1.gStr4Name = @"1号";
     NSLog(@"1  P1:%@",lP2);
    
    //数组是否可变不影响结果
    NSMutableArray *lArr1 = [NSMutableArray arrayWithArray:@[lP1]];
    NSMutableArray *lArr2 = [NSMutableArray arrayWithArray:@[lP2]];
    for (int i = 0; i < lArr1.count; ++i) {
        Person *lP1 = lArr1.firstObject;
         NSLog(@"2  P1:%@",lP.gStr4Name);
}

- (void)test5{
    Person *lP1 = [[Person alloc] init];
    lP1.gStr4Name = @"1号";
     NSLog(@"1  P1:%@",lP2);
    
    NSMutableArray *lArr1 = [NSMutableArray arrayWithArray:@[lP1]];
    NSMutableArray *lArr2 = [NSMutableArray arrayWithArray:@[lP2]];
    for (int i = 0; i < lArr1.count; ++i) {
        Person *lP1 = lArr1.firstObject;
         NSLog(@"2  P1:%@",lP1);
        for (int j = 0; j < lArr2.count; ++j) {
            Person *lP2 = lArr2.lastObject;
            
            //想改变数组内容,必须用系统方法!
            [lArr1 replaceObjectAtIndex:0 withObject:lP2];
        }
         NSLog(@"3  P1:%@",lP.gStr4Name);
}


@end

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...