美文网首页
修饰数组时用copy还是strong?

修饰数组时用copy还是strong?

作者: nunca | 来源:发表于2018-03-13 10:09 被阅读0次

    一、数据源是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?

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