• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 如何在不更改原始内容的情况下操作 NSDictionary 内容的副本

[复制链接]
菜鸟教程小白 发表于 2022-12-12 17:30:38 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

编辑

以下“更简单”的代码按预期工作。请参阅下面的代码,并在评论中解释我的观察结果。

- (void) changeDictValue
{
//If the method just uses the line below, then calling changeDictValue has no impact on self.bcastSeqNumList
NSMutableDictionary *seqListToUpdate = [NSMutableDictionary dictionaryWithDictionary:self.bcastSeqNumList] ;

//But if it instead uses the line below, calling changeDictValue does change self.bcastSeqNumList  
NSMutableDictionary *seqListToUpdate = self.bcastSeqNumList ;

seqListToUpdate[@(lastContSeqType)]=@(0) ;
seqListToUpdate[@(maxRcvdSeqType)]=@(1) ;
seqListToUpdate[@(missingSeqType)]=nil ;

}

所以,看起来我下面的代码中存在一些错误(或者在调用 dictionaryWithDictionary 期间如何处理 NSSet 的一些特殊 Obj-C 逻辑导致与 missingSeqType 键关联的 NSSet 受到影响,即使我正在对从 self.bcastSeqNumList 派生的新字典进行操作。有什么线索吗?

结束编辑

我有一个表示序列号的 NSDictionary
1.一个键(lastContSeqType)代表最大的序列号X,这样我就收到了所有的序列号<=X 2. 一键(maxRcvdSeqType)代表我目前收到的最大序列号 3.一个key(missingSeqType)代表一组“缺失的序列号”

我有一个这样的字典用于“广播消息”,并且有一个这样的字典用于每个带有远端的单播消息。

当我从服务器获取存储的序列号列表时,我使用存储在我端的序列号列表和接收到的序列号列表来确定要检索的序列号。

当我执行以下代码行时,

getMissingSequenceNumsFromServerNSDictionary *) dict 的第一个实现中,一切正常,bcastSeqNumList 正在更新,lastContSeqType更新为 4 并且 missingSeqType 为空。

在第二个实现中,我从 self.bcastSeqNumList 的内容创建一个新字典,然后操作这个“复制的”字典,我不希望 self.bcastSeqNumList 受方法内任何操作的影响。我看到 lastContSeqType 键不受影响,但 missingSeqType 键受到影响并变成一个空列表(即 NSNumber 对象@(4)正在被删除)。为什么会这样?

self.bcastSeqNumList= [@{@(lastContSeqType) : @(1), @(maxRcvdSeqType) : @(6), @(missingSeqType) : [NSMutableSet setWithObject(4)]
                                        } mutableCopy];

  NSLog(@"Bcast seq num list = %@",self.bcastSeqNumList) ;

  NSMutableDictionary *rcvdDict= [@{@"currBroadcastSeqNumStart" : @(5), @"currBroadcastSeqNumEnd" : @(6)
                             } mutableCopy];

  [self getMissingSequenceNumsFromServer:rcvdDict] ;

  NSLog(@"Bcast seq num list = %@",self.bcastSeqNumList) ;

案例 1 实现

- (void) getMissingSequenceNumsFromServerNSDictionary *) dict
{   
    NSInteger serverStoreSeqStart=[dict[@"currBroadcastSeqNumStart"] integerValue] ;
    NSInteger serverStoreSeqEnd=[dict[@"currBroadcastSeqNumEnd"] integerValue] ;
    NSMutableDictionary *seqListToUpdate = self.bcastSeqNumList ;


    NSInteger mySeq = [seqListToUpdate[@(lastContSeqType)] integerValue] ;


    if(mySeq < serverStoreSeqStart-1)
    {
        //Ask for all stored messages in server
        //[self getMessagesfromStart:serverStoreSeqStart toEnd:serverStoreSeqEnd] ;
        NSLog(@"Getting messages from %ld and to %ld",serverStoreSeqStart,serverStoreSeqEnd) ;

        NSLog(@"Never received seq nums %ld to %ld",mySeq+1,serverStoreSeqStart-1) ;

        NSInteger nextSeqToRemove ;


      for(nextSeqToRemove=mySeq+1;nextSeqToRemove<=serverStoreSeqStart-1;nextSeqToRemove++)
       {

         if([seqListToUpdate objectForKey(missingSeqType)])
         {
          if([seqListToUpdate[@(missingSeqType)] containsObject:[NSNumber numberWithInteger:nextSeqToRemove]])
           {
             NSLog(@"SeqNum %ld is in missing seq num list and being removed since we got server seq %ld > than this",(long)nextSeqToRemove,(long)serverStoreSeqStart) ;
            //Remove it
                            [seqListToUpdate[@(missingSeqType)] removeObject(nextSeqToRemove)] ;//
                            //If set is empty
                            if([seqListToUpdate[@(missingSeqType)] count] ==0)
                            {
                                //Nothing left in missing seq table. set it to nil and return
                                [seqListToUpdate removeObjectForKey(missingSeqType)] ;
                                seqListToUpdate[@(lastContSeqType)]=seqListToUpdate[@(maxRcvdSeqType)] ;
                                NSLog(@"Missing seq num list empty.  Setting last contig to max = %@",seqListToUpdate[@(lastContSeqType)]) ;

                                break ;
                            }
                 }
               }
               else
               {
                   //mising Seq Type has no elements, nothing to remove
                        break ;
               }
             }

             //At the end..if serverSeqToStore >= maxSeq, then lastCOnt=maxSeq and missing seq empty.
             //Else...if missing seq Empty, then

             seqListToUpdate[@(lastContSeqType)] = [NSNumber numberWithInteger:serverStoreSeqStart-1] ;

             if(seqListToUpdate[@(maxRcvdSeqType)] <= seqListToUpdate[@(lastContSeqType)])
             {
                    seqListToUpdate[@(maxRcvdSeqType)] = seqListToUpdate[@(lastContSeqType)] ;
                    //Set to misisng seq num list = nil
             }
             else
             {
                    //remove seqnums

             }
    }
    else if (mySeq < serverStoreSeqEnd)
    {
        //[self getMessagesfromStart:mySeq+1 toEnd:serverStoreSeqEnd] ;
        NSLog(@"Getting messages from %ld and to %ld",mySeq+1,serverStoreSeqEnd) ;
    }
    else if (mySeq > serverStoreSeqEnd)
    {
        NSLog(@"My stored sequence number %ld exceeds the max stored at server %ld",(long)mySeq,(long)serverStoreSeqEnd) ;
    }
}

案例 2 实现

下面一行

    seqListToUpdate = self.bcastSeqNumList ;

被下面的行替换,以便对 seqListToUpdate 的任何更改都不会影响 self.bcastSeqNumList 的内容

    seqListToUpdate = [NSMutableDictionary dictionaryWithDictionary:self.bcastSeqNumList] ;



Best Answer-推荐答案


您必须进行深层复制。目前,您只是将引用复制到相同的对象。您还必须复制字典中引用的对象。

easiest way of doing a deep copy is using NSKeyedArchiver归档和取消归档。

NSDictionary* deepCopy = [NSKeyedUnarchiver unarchiveObjectWithData:
      [NSKeyedArchiver archivedDataWithRootObjectriginalDict]];

关于ios - 如何在不更改原始内容的情况下操作 NSDictionary 内容的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34128112/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap