菜鸟教程小白 发表于 2022-12-13 05:35:46

ios - 集合中的可变对象


                                            <p><p> <a href="https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/ObjectMutability/ObjectMutability.html" rel="noreferrer noopener nofollow">From the docs</a> ,
在集合对象中存储可变对象可能会导致问题。如果某些集合包含的对象发生变异,则某些集合可能会变得无效甚至损坏,因为通过变异,这些对象会影响它们在集合中的放置方式。首先,作为散列集合中键的对象的属性,例如 NSDictionary 对象或 NSSet 对象,如果更改,如果更改的属性影响对象的散列或 isEqual: 方法的结果,则会破坏集合。 (如果集合中对象的哈希方法不依赖于它们的内部状态,那么损坏的可能性就较小。)其次,如果有序集合中的对象(例如排序数组)的属性发生了变化,这可能会影响对象如何与数组中的其他对象进行比较,从而导致排序无效。</p>

<p>但是当我记录结果时,该对象被完美地添加到集合中。其实这样做不安全?? </p>

<pre><code>-(void)mutableObjectsinCollections{
NSMutableArray *arr1 = [init];
NSMutableArray *arr2 = [init];
NSMutableArray *arr3 = [init];
NSMutableArray *arr4 = [init];


;
;
;
;

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

;
;
;
;

NSLog(@&#34;%@&#34;,dict);
}

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

for (int i = 1; i&lt;10; i++) {
      ];
}
}

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

for (int i = 10; i&lt;20; i++) {
    ];
}
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我会给你一个例子。</p>

<p>让我们为字典定义我们自己的可变键,注意它可以被复制,它定义了 <code>hash</code> 和相等性的实现。</p>

<pre><code>@interface MyKey : NSObject &lt;NSCopying&gt;

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

@end

@implementation MyKey

- (id)initWithData:(NSString *)data {
    self = ;

    self.keyData = data;

    return self;
}

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

    return key;
}

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

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

    MyKey *key = object;

    return ;
}

@end
</code></pre>

<p>现在让我们有一个简单的测试用例:</p>

<p>让我们定义一些键</p>

<pre><code>MyKey *key1 = [ initWithData:@&#34;key1&#34;];
MyKey *key2 = [ initWithData:@&#34;key2&#34;];
MyKey *keyX = [ initWithData:@&#34;XXX&#34;];
</code></pre>

<p>还有一本简单的字典</p>

<pre><code>NSDictionary *dictionary = @{key1: @&#34;value1&#34;, key2: @&#34;value2&#34;};
</code></pre>

<p>让我们看看里面有什么</p>

<pre><code>NSLog(@&#34;%lu&#34;, (unsigned long) dictionary.count);
NSLog(@&#34;%@&#34;, dictionary);
NSLog(@&#34;%@&#34;, );
NSLog(@&#34;%@&#34;, );
NSLog(@&#34;%@&#34;, );
</code></pre>

<p>给予(预期)</p>

<pre><code>2
{
    &#34;&lt;MyKey: 0x10010a8d0&gt;&#34; = value1;
    &#34;&lt;MyKey: 0x100108e40&gt;&#34; = value2;
}
value1
value2
(null)
</code></pre>

<p>现在让我们改变一个键的值</p>

<pre><code>[(MyKey *)[ objectAtIndex:0] setKeyData:@&#34;XXX&#34;];
</code></pre>

<p>让我们再看看里面是什么</p>

<pre><code>NSLog(@&#34;%lu&#34;, (unsigned long) dictionary.count);
NSLog(@&#34;%@&#34;, dictionary);
NSLog(@&#34;%@&#34;, );
NSLog(@&#34;%@&#34;, );
NSLog(@&#34;%@&#34;, );
</code></pre>

<p>给予</p>

<pre><code>2   //expected
{
    &#34;&lt;MyKey: 0x10010a8d0&gt;&#34; = (null);//huh, null value?
    &#34;&lt;MyKey: 0x100108e40&gt;&#34; = value2;
}
(null) //huh?
value2
(null) //huh?
</code></pre>

<p><b>出了什么问题?</b></p>

<p>字典的内部结构是使用哈希表实现的。他们键的 <code>hash</code> 用于搜索值。一旦我们改变了key中的数据,hash值也会改变。因此,字典将无法找到为给定键存储的值。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 集合中的可变对象,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/20368173/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/20368173/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 集合中的可变对象