修饰数组时用copy还是strong?

一、数据源是NSMutableArray类型

@property(nonatomic, copy) NSMutableArray *aCopyMutArray;
@property(nonatomic, copy) NSArray *aCopyArray;
@property(nonatomic, strong) NSMutableArray *aStrongMutArray;
@property(nonatomic, strong) NSArray *aStrongArray;

首先创建了四个不同类型的数组对象
并赋上相同的值,可变型的数组

    NSMutableArray *testArray = [NSMutableArray arrayWithObjects:@"1",@"2", nil];

    self.aCopyArray = testArray;
    self.aStrongArray = testArray;
    self.aCopyMutArray = testArray;
    self.aStrongMutArray = testArray;

    [testArray addObject:@"3"];
    NSLog(@"=================step 1 = =========");
    [self printArrays];
2018-03-12 16:44:33.839259+0800 Nunca[10196:1294488] =================step 1 = =========
2018-03-12 16:44:33.839567+0800 Nunca[10196:1294488] testArray = (
    1,
    2,
    3
),isa = 0x600000246ed0
2018-03-12 16:44:33.839729+0800 Nunca[10196:1294488] aCopyArray = (
    1,
    2
),isa = 0x600000229b80
2018-03-12 16:44:33.839962+0800 Nunca[10196:1294488] aStrongArray = (
    1,
    2,
    3
),isa = 0x600000246ed0
2018-03-12 16:44:33.840212+0800 Nunca[10196:1294488] aCopyMutArray = (
    1,
    2
),isa = 0x60000022a5a0
2018-03-12 16:44:33.840343+0800 Nunca[10196:1294488] aStrongMutArray = (
    1,
    2,
    3
),isa = 0x600000246ed0

改变testArray的值,可见以strong修饰的对象指针指向的是同testArray同一块内存,而以copy修饰的对象则被分配了新的内存

    NSLog(@"=================step 2  = =========");
    
    if ([self.aCopyMutArray isKindOfClass:[NSMutableArray class]]) {
        [self.aCopyMutArray addObject:@"4"];
        NSLog(@"aCopyMutArray.class = NSMutableArray");
    } else {
        NSLog(@"aCopyMutArray.class = NSArray");
    }
    
    if ([self.aStrongArray isKindOfClass:[NSMutableArray class]]) {
        void (*imp) (id,SEL,id) = (void (*)(id,SEL,id))[self.aStrongArray methodForSelector:@selector(addObject:)];
        imp(self.aStrongArray,@selector(addObject:),@"4");
        NSLog(@"aStrongArray.class = NSMutableArray");
    } else {
        NSLog(@"aStrongArray.class = NSArray");
    }
    
    [self printArrays];
2018-03-12 16:44:33.840434+0800 Nunca[10196:1294488] =================step 2  = =========
2018-03-12 16:44:33.840638+0800 Nunca[10196:1294488] aCopyMutArray.class = NSArray
2018-03-12 16:44:33.840850+0800 Nunca[10196:1294488] aStrongArray.class = NSMutableArray
2018-03-12 16:44:33.841007+0800 Nunca[10196:1294488] aCopyArray = (
    1,
    2
),isa = 0x600000229b80
2018-03-12 16:44:33.841099+0800 Nunca[10196:1294488] aStrongArray = (
    1,
    2,
    3,
    4
),isa = 0x600000246ed0
2018-03-12 16:44:33.841277+0800 Nunca[10196:1294488] aCopyMutArray = (
    1,
    2
),isa = 0x60000022a5a0
2018-03-12 16:44:33.841462+0800 Nunca[10196:1294488] aStrongMutArray = (
    1,
    2,
    3,
    4
),isa = 0x600000246ed0

aCopyMutArray 虽然注明的是NSMutableArray类型,但由于copy属性,实际上是不可变类型,aStrongArray虽然标明是NSArray类型,但由于strong属性,实际上的真实类型是跟数据源(testArray)保持一致。

二、数据源是NSArray类型

    NSArray *testArray = [NSArray arrayWithObjects:@"1",@"2", nil];
    self.aCopyArray = testArray;
    self.aStrongArray = testArray;
    self.aCopyMutArray =  [NSMutableArray arrayWithArray:testArray];
    self.aStrongMutArray = [NSMutableArray arrayWithArray:testArray];
    NSLog(@"=================step 1 = =========");
    [self printArrays];
2018-03-12 16:59:21.242880+0800 Nunca[10595:1312829] =================step 1 = =========
2018-03-12 16:59:21.243138+0800 Nunca[10595:1312829] testArray = (
    1,
    2
),isa = 0x60000023b7a0
2018-03-12 16:59:21.243740+0800 Nunca[10595:1312829] aCopyArray = (
    1,
    2
),isa = 0x60000023b7a0
2018-03-12 16:59:21.244087+0800 Nunca[10595:1312829] aStrongArray = (
    1,
    2
),isa = 0x60000023b7a0
2018-03-12 16:59:21.244433+0800 Nunca[10595:1312829] aCopyMutArray = (
    1,
    2
),isa = 0x60000002f780
2018-03-12 16:59:21.244684+0800 Nunca[10595:1312829] aStrongMutArray = (
    1,
    2
),isa = 0x600000243240

可见,当数据源是不可变类型时,不管对象是用strong还是用copy修饰,都会指向数据源同一块内存,不会再新创建

    NSLog(@"=================step 2  = =========");
    if ([self.aCopyMutArray isKindOfClass:[NSMutableArray class]]) {
        [self.aCopyMutArray addObject:@"4"];
        NSLog(@"aCopyMutArray.class = NSMutableArray");
    } else {
        NSLog(@"aCopyMutArray.class = NSArray");
    }
    
    if ([self.aStrongMutArray isKindOfClass:[NSMutableArray class]]) {
        [self.aStrongMutArray addObject:@"4"];
        NSLog(@"aStrongMutArray.class = NSMutableArray");
    } else {
        NSLog(@"aStrongMutArray.class = NSArray");
    }    
2018-03-12 16:59:21.244815+0800 Nunca[10595:1312829] =================step 2  = =========
2018-03-12 16:59:21.244989+0800 Nunca[10595:1312829] aCopyMutArray.class = NSArray
2018-03-12 16:59:21.245375+0800 Nunca[10595:1312829] aStrongMutArray.class = NSMutableArray

以copy修饰的aCopyMutArray仍然是不可变类型

结论:

  • 当源数据与想持有的对象都是NSArray类型时,直接用strong或copy修饰都可以,效果也是一样;
  • 当源数据为NSMutableArray类型,想持有的对象为NSArray时,用copy修饰;
  • 当源数据为NSArray或NSMutableArray类型,想持有的对象为NSMutableArray时,用strong修饰对象并通过 [NSMutableArray arrayWithArray:testArray] 赋值,即可保证对象的可变性又能摆脱源数据变化时带来的影响。

你可能感兴趣的:(修饰数组时用copy还是strong?)