Ios 集合中的可变对象

Ios 集合中的可变对象,ios,mutable,Ios,Mutable,,, 在集合对象中存储可变对象可能会导致问题。如果包含的对象发生变化,某些集合可能会变得无效甚至损坏,因为通过变化,这些对象可能会影响它们在集合中的放置方式。首先,在散列集合中作为键的对象(如NSDictionary对象或NSSet对象)的属性如果更改,将损坏集合(如果更改的属性影响对象的散列或isEqual:方法的结果)。(如果集合中对象的哈希方法不依赖于其内部状态,则损坏的可能性较小。)其次,如果有序集合(如排序数组)中的对象的属性发生更改,这可能会影响该对象与数组中其他对象的比较方式,从而

,, 在集合对象中存储可变对象可能会导致问题。如果包含的对象发生变化,某些集合可能会变得无效甚至损坏,因为通过变化,这些对象可能会影响它们在集合中的放置方式。首先,在散列集合中作为键的对象(如NSDictionary对象或NSSet对象)的属性如果更改,将损坏集合(如果更改的属性影响对象的散列或isEqual:方法的结果)。(如果集合中对象的哈希方法不依赖于其内部状态,则损坏的可能性较小。)其次,如果有序集合(如排序数组)中的对象的属性发生更改,这可能会影响该对象与数组中其他对象的比较方式,从而导致排序无效

但是当我记录结果时,对象被完美地添加到集合中。实际上这样做是不安全的

-(void)mutableObjectsinCollections{
 NSMutableArray *arr1 = [[NSMutableArray alloc]init];
 NSMutableArray *arr2 = [[NSMutableArray alloc]init];
 NSMutableArray *arr3 = [[NSMutableArray alloc]init];
 NSMutableArray *arr4 = [[NSMutableArray alloc]init];


 [self addObjectsToArrayBefore:arr1];
 [self addObjectsToArrayBefore:arr2];
 [self addObjectsToArrayBefore:arr3];
 [self addObjectsToArrayBefore:arr4];

 NSDictionary *dict = @{@"arr1": arr1,@"arr2": arr2,@"arr3": arr3,@"arr4": arr4,@"arr5": arr5};
 NSLog(@"%@",dict);

 [self addObjectsToArrayAfter:arr1];
 [self addObjectsToArrayAfter:arr2];
 [self addObjectsToArrayAfter:arr3];
 [self addObjectsToArrayAfter:arr4];

 NSLog(@"%@",dict);
}

-(void)addObjectsToArrayBefore:(NSMutableArray *)arr{

for (int i = 1; i<10; i++) {
      [arr addObject:[NSNumber numberWithInteger:i]];
}
}

-(void)addObjectsToArrayAfter:(NSMutableArray *)arr{

for (int i = 10; i<20; i++) {
    [arr addObject:[NSNumber numberWithInteger:i]];
  }
}
-(void)可变对象集合{
NSMutableArray*arr1=[[NSMutableArray alloc]init];
NSMutableArray*arr2=[[NSMutableArray alloc]init];
NSMutableArray*arr3=[[NSMutableArray alloc]init];
NSMutableArray*arr4=[[NSMutableArray alloc]init];
[self addObjectsToArrayBefore:arr1];
[self addObjectsToArrayBefore:arr2];
[self addObjectsToArrayBefore:arr3];
[self addObjectsToArrayBefore:arr4];
NSDictionary*dict={“arr1”:arr1,@“arr2”:arr2,@“arr3”:arr3,@“arr4”:arr4,@“arr5”:arr5};
NSLog(@“%@”,dict);
[self addobjectstoarrayaafter:arr1];
[self addobjectstoarrayaafter:arr2];
[self addObjectsToArrayAfter:arr3];
[self addobjectstoarrayaafter:arr4];
NSLog(@“%@”,dict);
}
-(void)addObjectsToArrayBefore:(NSMutableArray*)arr{

对于(int i=1;i代码是安全的。NSDictionary不关心键值对中值的可变性。它关心的是键的可变性,在您的情况下,这些键属于NSString(不可变)类型


也不要期望,如果确实存在可变性问题,它会以异常或崩溃的形式表现出来。它可能会在查询集合时给出不正确的结果而不被注意地通过,因此您所做的测试没有多大帮助。

代码是安全的。NSDictionary不关心键值pa中值的可变性它真正关心的是键的可变性,在您的例子中,这些键是NSString(不可变)类型


也不要期望,如果确实存在易变性问题,它会以异常或崩溃的形式表现出来。在查询集合时,它可能只是给出错误的结果而未被注意到,因此您所做的测试没有多大帮助。

我将向您展示一个示例

让我们为字典定义我们自己的可变键,注意它可以被复制,它定义了一个
hash
和相等的实现

@interface MyKey : NSObject <NSCopying>

@property (nonatomic, copy, readwrite) NSString *keyData;

@end

@implementation MyKey

- (id)initWithData:(NSString *)data {
    self = [super init];

    self.keyData = data;

    return self;
}

- (id)copyWithZone:(NSZone *)zone {
    MyKey *key = (MyKey *) [[[self class] alloc] init];
    key.keyData = self.keyData;

    return key;
}

- (NSUInteger)hash {
    return self.keyData.length;
}

- (BOOL)isEqual:(id)object {
    if (![object isMemberOfClass:[self class]]) {
        return NO;
    }

    MyKey *key = object;

    return [self.keyData isEqualToString:key.keyData];
}

@end
还有一本简单的字典

NSDictionary *dictionary = @{key1: @"value1", key2: @"value2"};
让我们看看里面是什么

NSLog(@"%lu", (unsigned long) dictionary.count);
NSLog(@"%@", dictionary);
NSLog(@"%@", [dictionary objectForKey:key1]);
NSLog(@"%@", [dictionary objectForKey:key2]);
NSLog(@"%@", [dictionary objectForKey:keyX]);
给出(预期)

让我们再看看里面是什么

NSLog(@"%lu", (unsigned long) dictionary.count);
NSLog(@"%@", dictionary);
NSLog(@"%@", [dictionary objectForKey:key1]);
NSLog(@"%@", [dictionary objectForKey:key2]);
NSLog(@"%@", [dictionary objectForKey:keyX]);
给予

2//
{
“”=(null);//嗯,null值?
“”=值2;
}
(空)//嗯?
价值2
(空)//嗯?
出了什么问题


字典的内部结构是使用哈希表实现的。它们键的
哈希
用于搜索值。一旦我们更改键中的数据,哈希值也会更改。因此,字典将无法找到为给定键存储的值。

我将向您展示一个示例

让我们为字典定义我们自己的可变键,注意它可以被复制,它定义了一个
hash
和相等的实现

@interface MyKey : NSObject <NSCopying>

@property (nonatomic, copy, readwrite) NSString *keyData;

@end

@implementation MyKey

- (id)initWithData:(NSString *)data {
    self = [super init];

    self.keyData = data;

    return self;
}

- (id)copyWithZone:(NSZone *)zone {
    MyKey *key = (MyKey *) [[[self class] alloc] init];
    key.keyData = self.keyData;

    return key;
}

- (NSUInteger)hash {
    return self.keyData.length;
}

- (BOOL)isEqual:(id)object {
    if (![object isMemberOfClass:[self class]]) {
        return NO;
    }

    MyKey *key = object;

    return [self.keyData isEqualToString:key.keyData];
}

@end
还有一本简单的字典

NSDictionary *dictionary = @{key1: @"value1", key2: @"value2"};
让我们看看里面是什么

NSLog(@"%lu", (unsigned long) dictionary.count);
NSLog(@"%@", dictionary);
NSLog(@"%@", [dictionary objectForKey:key1]);
NSLog(@"%@", [dictionary objectForKey:key2]);
NSLog(@"%@", [dictionary objectForKey:keyX]);
给出(预期)

让我们再看看里面是什么

NSLog(@"%lu", (unsigned long) dictionary.count);
NSLog(@"%@", dictionary);
NSLog(@"%@", [dictionary objectForKey:key1]);
NSLog(@"%@", [dictionary objectForKey:key2]);
NSLog(@"%@", [dictionary objectForKey:keyX]);
给予

2//
{
“”=(null);//嗯,null值?
“”=值2;
}
(空)//嗯?
价值2
(空)//嗯?
出了什么问题

字典的内部结构是使用哈希表实现的。它们键的
hash
用于搜索值。一旦我们更改键中的数据,哈希值也会更改。因此,字典将无法找到为给定键存储的值