NSMutableDictionary实例化初始化后还是nil
NSMutableDictionary Is Still Nil After Being Instantiated And Initialized
以下是每次收到发言人信息时调用的方法。
- (void)handleGroupingFromReceivedSpeakerInfo:(SpeakerInfo *)speakerInfo
{
GroupInfo *groupInfo = [_IP_GroupInfo_Map objectForKey:speakerInfo.mGroupIP];
if(groupInfo == nil)
{
groupInfo = [[GroupInfo alloc] init];
groupInfo.mIP = speakerInfo.mGroupIP;
groupInfo.isTemp = YES;
NSLog(@"HandleGrouping: New temp group %@", groupInfo.mIP);
}
if(groupInfo.isTemp)
{
if(![groupInfo.mSpeakerIDList containsObject:[@(speakerInfo.mID) stringValue]])
{
[groupInfo.mSpeakerIDList addObject:[@(speakerInfo.mID) stringValue]];
NSLog(@"HandleGrouping: added new member with id %@ temp group with ip %@", [@(speakerInfo.mID) stringValue], groupInfo.mIP);
[_IP_GroupInfo_Map setObject:groupInfo forKey:groupInfo.mIP];
}
}
}
现在我将稍微解释一下代码的作用。
每收到一个speaker info,就会得到存储的GroupInfo
,用key得到,speakerInfo.mGroupIP
如果 groupInfo 是 nil 然后简单地实例化一个新的,然后将扬声器信息的 ID 添加到 组信息
如果不是,则继续将 speakerInfo 添加到现有 GroupInfo
好的,问题来了,看一下Log(请不要介意其他的Log信息,只有以“HandleGrouping:”开头的):
Discovered speaker with id 6494094734139439904
2015-08-28 17:41:53.756 soulbeats[13558:3307] Added speakerID: 6494094734139439904 to AllSpeakersIDList
2015-08-28 17:41:53.758 soulbeats[13558:1803] Discovered speaker with id 72243140485806144
2015-08-28 17:41:53.763 soulbeats[13558:3307] Old speaker info is null
2015-08-28 17:41:53.765 soulbeats[13558:1803] Added speakerID: 72243140485806144 to AllSpeakersIDList
2015-08-28 17:41:53.770 soulbeats[13558:3307] HandleGrouping: New temp group 239.11.11.12
2015-08-28 17:41:53.772 soulbeats[13558:1803] Old speaker info is null
2015-08-28 17:41:53.777 soulbeats[13558:3307] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 17:41:53.779 soulbeats[13558:1803] HandleGrouping: New temp group 239.11.11.12
2015-08-28 17:41:53.785 soulbeats[13558:3307] Discovered speaker with id 7782687177520836128
2015-08-28 17:41:53.788 soulbeats[13558:1803] HandleGrouping: added new member with id 72243140485806144 temp group with ip 239.11.11.12
2015-08-28 17:41:53.794 soulbeats[13558:3307] Added speakerID: 7782687177520836128 to AllSpeakersIDList
2015-08-28 17:41:53.802 soulbeats[13558:3307] Old speaker info is null
2015-08-28 17:41:53.807 soulbeats[13558:3307] HandleGrouping: added new member with id 7782687177520836128 temp group with ip 239.11.11.12
2015-08-28 17:41:55.711 soulbeats[13558:60b] SendBrowseCmd: browse again!!!
2015-08-28 17:41:55.719 soulbeats[13558:60b] SendBrowseCmd: refresh!!!
2015-08-28 17:41:55.721 soulbeats[13558:60b] Refresh: found one temp group with ip 239.11.11.12 with speakerIDListCount 2
从上面可以看出,groupInfo被实例化了TWICE。您可以看到日志消息 "New temp group 239.11.11.12" 出现 TWICE.
2015-08-28 17:41:53.770 soulbeats[13558:3307] HandleGrouping: New temp group 239.11.11.12
2015-08-28 17:41:53.772 soulbeats[13558:1803] Old speaker info is null
2015-08-28 17:41:53.777 soulbeats[13558:3307] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 17:41:53.779 soulbeats[13558:1803] HandleGrouping: New temp group 239.11.11.12
我不明白为什么会这样。我得到了具有相同密钥的 groupInfo 对象,这是接收到的 speakerInfo 的 ip,239.11.11.12。所以我希望在第一次调用此方法时,groupInfo 应该为 nil。但在那之后,由于我已经在其中添加了一个 speakerInfo.mID 并将其再次设置为 _IP_GroupInfo_Map 字典,因此在下次调用时 groupInfo 不应为 nil方法。
附加信息:
我这样声明 NSMutableDictionary:
@property (nonatomic, strong) NSMutableDictionary *IP_GroupInfo_Map;
我该怎么做才能解决这个问题?请帮忙。非常感谢。
--------- 更新:添加了 NSLog(@"%@", self) --------------
2015-08-28 18:41:28.497 soulbeats[13652:5d03] Discovered speaker with id 7782687177520836128
2015-08-28 18:41:28.505 soulbeats[13652:1803] <MultiroomPlay: 0x1760ba90>
2015-08-28 18:41:28.507 soulbeats[13652:3903] <MultiroomPlay: 0x1760ba90>
2015-08-28 18:41:28.508 soulbeats[13652:5d03] Added speakerID: 7782687177520836128 to AllSpeakersIDList
2015-08-28 18:41:28.516 soulbeats[13652:1803] HandleGrouping: New temp group 239.11.11.12
2015-08-28 18:41:28.518 soulbeats[13652:3903] HandleGrouping: New temp group 239.11.11.12
2015-08-28 18:41:28.519 soulbeats[13652:5d03] Old speaker info is null
2015-08-28 18:41:28.527 soulbeats[13652:1803] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 18:41:28.530 soulbeats[13652:3903] HandleGrouping: added new member with id 72243140485806144 temp group with ip 239.11.11.12
2015-08-28 18:41:28.531 soulbeats[13652:5d03] <MultiroomPlay: 0x1760ba90>
2015-08-28 18:41:28.543 soulbeats[13652:5d03] HandleGrouping: added new member with id 7782687177520836128 temp group with ip 239.11.11.12
可以看出,id正好是SAME.
-------- 另一项更新:添加了关于如何初始化 Class 的代码 ------
+ (MultiroomPlay *)getMultiroomPlay
{
static MultiroomPlay *sharedMultiroomPlay;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,
^{
sharedMultiroomPlay = [[MultiroomPlay alloc] init];
});
return sharedMultiroomPlay;
}
- (id)init
{
self = [super init];
if (self)
{
[self openSocket];
_allSpeakersIDList = [[NSMutableArray alloc] init];
_allPermGroupsIDList = [[NSMutableArray alloc] init];
_allGroupsIPList = [[NSMutableArray alloc] init];
_allUngroupedSpeakersList = [[NSMutableArray alloc] init];
_allUngroupedPermGroupsList = [[NSMutableArray alloc] init];
_allTempGroupsList = [[NSMutableArray alloc] init];
_tempGroupMemberRemoveSeqList = [[NSMutableArray alloc] init];
_ID_TCPConnection_Map = [[NSMutableDictionary alloc] init];
_ID_SpeakerInfo_Map = [[NSMutableDictionary alloc] init];
_ID_PermGroupInfo_Map = [[NSMutableDictionary alloc] init];
_IP_GroupInfo_Map = [NSMutableDictionary dictionary]; // <--Look here
_IP_PlayerInfo_Map = [[NSMutableDictionary alloc] init];
_IP_PlayBackTimer_Map = [[NSMutableDictionary alloc] init];
_IP_FinishSeqNum_Map = [[NSMutableDictionary alloc] init];
}
return self;
}
--------- 为 GroupInfo 的值添加日志 -----------
2015-08-28 19:07:29.043 soulbeats[13709:3307] Discovered speaker with id 6494094734139439904
2015-08-28 19:07:29.046 soulbeats[13709:1803] Discovered speaker with id 72243140485806144
2015-08-28 19:07:29.050 soulbeats[13709:3307] Added speakerID: 6494094734139439904 to AllSpeakersIDList
2015-08-28 19:07:29.052 soulbeats[13709:1803] Added speakerID: 72243140485806144 to AllSpeakersIDList
2015-08-28 19:07:29.058 soulbeats[13709:3307] Old speaker info is null
2015-08-28 19:07:29.060 soulbeats[13709:1803] Old speaker info is null
2015-08-28 19:07:29.066 soulbeats[13709:3307] <MultiroomPlay: 0x1460e920>
2015-08-28 19:07:29.069 soulbeats[13709:1803] <MultiroomPlay: 0x1460e920>
2015-08-28 19:07:29.074 soulbeats[13709:3307] Value of Groupinfo: (null)
2015-08-28 19:07:29.076 soulbeats[13709:1803] Value of Groupinfo: (null)
2015-08-28 19:07:29.081 soulbeats[13709:3307] HandleGrouping: New temp group 239.11.11.12
2015-08-28 19:07:29.083 soulbeats[13709:1803] HandleGrouping: New temp group 239.11.11.12
2015-08-28 19:07:29.089 soulbeats[13709:3307] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 19:07:29.091 soulbeats[13709:1803] HandleGrouping: added new member with id 72243140485806144 temp group with ip 239.11.11.12
2015-08-28 19:07:29.098 soulbeats[13709:3307] Discovered speaker with id 7782687177520836128
2015-08-28 19:07:29.250 soulbeats[13709:3307] Added speakerID: 7782687177520836128 to AllSpeakersIDList
2015-08-28 19:07:29.332 soulbeats[13709:3307] Old speaker info is null
2015-08-28 19:07:29.380 soulbeats[13709:3307] <MultiroomPlay: 0x1460e920>
2015-08-28 19:07:29.394 soulbeats[13709:3307] Value of Groupinfo: <GroupInfo: 0x1589aad0>
2015-08-28 19:07:29.400 soulbeats[13709:3307] HandleGrouping: added new member with id 7782687177520836128 temp group with ip 239.11.11.12
在适当的初始化方法中添加以下行
_IP_GroupInfo_Map = [NSMutableDictionary dictionary];
原来你的程序是多线程的。用 @synchronized
包围您的代码并获得预期的输出显示了这一点。
@synchronized
导致块以原子方式执行。在两个线程可以输入您的代码之前,它们都发现您的字典为 nil 并且都实例化了它,现在两个(或更多)线程各自在同步块的顶部等待,直到其他线程退出。
但是,您不应只接受“它现在可以工作”,您应该尝试找出为什么您不认为它是多线程的!
(此问题的部分内容已在 chat 中讨论)。
以下是每次收到发言人信息时调用的方法。
- (void)handleGroupingFromReceivedSpeakerInfo:(SpeakerInfo *)speakerInfo
{
GroupInfo *groupInfo = [_IP_GroupInfo_Map objectForKey:speakerInfo.mGroupIP];
if(groupInfo == nil)
{
groupInfo = [[GroupInfo alloc] init];
groupInfo.mIP = speakerInfo.mGroupIP;
groupInfo.isTemp = YES;
NSLog(@"HandleGrouping: New temp group %@", groupInfo.mIP);
}
if(groupInfo.isTemp)
{
if(![groupInfo.mSpeakerIDList containsObject:[@(speakerInfo.mID) stringValue]])
{
[groupInfo.mSpeakerIDList addObject:[@(speakerInfo.mID) stringValue]];
NSLog(@"HandleGrouping: added new member with id %@ temp group with ip %@", [@(speakerInfo.mID) stringValue], groupInfo.mIP);
[_IP_GroupInfo_Map setObject:groupInfo forKey:groupInfo.mIP];
}
}
}
现在我将稍微解释一下代码的作用。
每收到一个speaker info,就会得到存储的
GroupInfo
,用key得到,speakerInfo.mGroupIP如果 groupInfo 是 nil 然后简单地实例化一个新的,然后将扬声器信息的 ID 添加到 组信息
如果不是,则继续将 speakerInfo 添加到现有
GroupInfo
好的,问题来了,看一下Log(请不要介意其他的Log信息,只有以“HandleGrouping:”开头的):
Discovered speaker with id 6494094734139439904
2015-08-28 17:41:53.756 soulbeats[13558:3307] Added speakerID: 6494094734139439904 to AllSpeakersIDList
2015-08-28 17:41:53.758 soulbeats[13558:1803] Discovered speaker with id 72243140485806144
2015-08-28 17:41:53.763 soulbeats[13558:3307] Old speaker info is null
2015-08-28 17:41:53.765 soulbeats[13558:1803] Added speakerID: 72243140485806144 to AllSpeakersIDList
2015-08-28 17:41:53.770 soulbeats[13558:3307] HandleGrouping: New temp group 239.11.11.12
2015-08-28 17:41:53.772 soulbeats[13558:1803] Old speaker info is null
2015-08-28 17:41:53.777 soulbeats[13558:3307] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 17:41:53.779 soulbeats[13558:1803] HandleGrouping: New temp group 239.11.11.12
2015-08-28 17:41:53.785 soulbeats[13558:3307] Discovered speaker with id 7782687177520836128
2015-08-28 17:41:53.788 soulbeats[13558:1803] HandleGrouping: added new member with id 72243140485806144 temp group with ip 239.11.11.12
2015-08-28 17:41:53.794 soulbeats[13558:3307] Added speakerID: 7782687177520836128 to AllSpeakersIDList
2015-08-28 17:41:53.802 soulbeats[13558:3307] Old speaker info is null
2015-08-28 17:41:53.807 soulbeats[13558:3307] HandleGrouping: added new member with id 7782687177520836128 temp group with ip 239.11.11.12
2015-08-28 17:41:55.711 soulbeats[13558:60b] SendBrowseCmd: browse again!!!
2015-08-28 17:41:55.719 soulbeats[13558:60b] SendBrowseCmd: refresh!!!
2015-08-28 17:41:55.721 soulbeats[13558:60b] Refresh: found one temp group with ip 239.11.11.12 with speakerIDListCount 2
从上面可以看出,groupInfo被实例化了TWICE。您可以看到日志消息 "New temp group 239.11.11.12" 出现 TWICE.
2015-08-28 17:41:53.770 soulbeats[13558:3307] HandleGrouping: New temp group 239.11.11.12
2015-08-28 17:41:53.772 soulbeats[13558:1803] Old speaker info is null
2015-08-28 17:41:53.777 soulbeats[13558:3307] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 17:41:53.779 soulbeats[13558:1803] HandleGrouping: New temp group 239.11.11.12
我不明白为什么会这样。我得到了具有相同密钥的 groupInfo 对象,这是接收到的 speakerInfo 的 ip,239.11.11.12。所以我希望在第一次调用此方法时,groupInfo 应该为 nil。但在那之后,由于我已经在其中添加了一个 speakerInfo.mID 并将其再次设置为 _IP_GroupInfo_Map 字典,因此在下次调用时 groupInfo 不应为 nil方法。
附加信息:
我这样声明 NSMutableDictionary:
@property (nonatomic, strong) NSMutableDictionary *IP_GroupInfo_Map;
我该怎么做才能解决这个问题?请帮忙。非常感谢。
--------- 更新:添加了 NSLog(@"%@", self) --------------
2015-08-28 18:41:28.497 soulbeats[13652:5d03] Discovered speaker with id 7782687177520836128
2015-08-28 18:41:28.505 soulbeats[13652:1803] <MultiroomPlay: 0x1760ba90>
2015-08-28 18:41:28.507 soulbeats[13652:3903] <MultiroomPlay: 0x1760ba90>
2015-08-28 18:41:28.508 soulbeats[13652:5d03] Added speakerID: 7782687177520836128 to AllSpeakersIDList
2015-08-28 18:41:28.516 soulbeats[13652:1803] HandleGrouping: New temp group 239.11.11.12
2015-08-28 18:41:28.518 soulbeats[13652:3903] HandleGrouping: New temp group 239.11.11.12
2015-08-28 18:41:28.519 soulbeats[13652:5d03] Old speaker info is null
2015-08-28 18:41:28.527 soulbeats[13652:1803] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 18:41:28.530 soulbeats[13652:3903] HandleGrouping: added new member with id 72243140485806144 temp group with ip 239.11.11.12
2015-08-28 18:41:28.531 soulbeats[13652:5d03] <MultiroomPlay: 0x1760ba90>
2015-08-28 18:41:28.543 soulbeats[13652:5d03] HandleGrouping: added new member with id 7782687177520836128 temp group with ip 239.11.11.12
可以看出,id正好是SAME.
-------- 另一项更新:添加了关于如何初始化 Class 的代码 ------
+ (MultiroomPlay *)getMultiroomPlay
{
static MultiroomPlay *sharedMultiroomPlay;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,
^{
sharedMultiroomPlay = [[MultiroomPlay alloc] init];
});
return sharedMultiroomPlay;
}
- (id)init
{
self = [super init];
if (self)
{
[self openSocket];
_allSpeakersIDList = [[NSMutableArray alloc] init];
_allPermGroupsIDList = [[NSMutableArray alloc] init];
_allGroupsIPList = [[NSMutableArray alloc] init];
_allUngroupedSpeakersList = [[NSMutableArray alloc] init];
_allUngroupedPermGroupsList = [[NSMutableArray alloc] init];
_allTempGroupsList = [[NSMutableArray alloc] init];
_tempGroupMemberRemoveSeqList = [[NSMutableArray alloc] init];
_ID_TCPConnection_Map = [[NSMutableDictionary alloc] init];
_ID_SpeakerInfo_Map = [[NSMutableDictionary alloc] init];
_ID_PermGroupInfo_Map = [[NSMutableDictionary alloc] init];
_IP_GroupInfo_Map = [NSMutableDictionary dictionary]; // <--Look here
_IP_PlayerInfo_Map = [[NSMutableDictionary alloc] init];
_IP_PlayBackTimer_Map = [[NSMutableDictionary alloc] init];
_IP_FinishSeqNum_Map = [[NSMutableDictionary alloc] init];
}
return self;
}
--------- 为 GroupInfo 的值添加日志 -----------
2015-08-28 19:07:29.043 soulbeats[13709:3307] Discovered speaker with id 6494094734139439904
2015-08-28 19:07:29.046 soulbeats[13709:1803] Discovered speaker with id 72243140485806144
2015-08-28 19:07:29.050 soulbeats[13709:3307] Added speakerID: 6494094734139439904 to AllSpeakersIDList
2015-08-28 19:07:29.052 soulbeats[13709:1803] Added speakerID: 72243140485806144 to AllSpeakersIDList
2015-08-28 19:07:29.058 soulbeats[13709:3307] Old speaker info is null
2015-08-28 19:07:29.060 soulbeats[13709:1803] Old speaker info is null
2015-08-28 19:07:29.066 soulbeats[13709:3307] <MultiroomPlay: 0x1460e920>
2015-08-28 19:07:29.069 soulbeats[13709:1803] <MultiroomPlay: 0x1460e920>
2015-08-28 19:07:29.074 soulbeats[13709:3307] Value of Groupinfo: (null)
2015-08-28 19:07:29.076 soulbeats[13709:1803] Value of Groupinfo: (null)
2015-08-28 19:07:29.081 soulbeats[13709:3307] HandleGrouping: New temp group 239.11.11.12
2015-08-28 19:07:29.083 soulbeats[13709:1803] HandleGrouping: New temp group 239.11.11.12
2015-08-28 19:07:29.089 soulbeats[13709:3307] HandleGrouping: added new member with id 6494094734139439904 temp group with ip 239.11.11.12
2015-08-28 19:07:29.091 soulbeats[13709:1803] HandleGrouping: added new member with id 72243140485806144 temp group with ip 239.11.11.12
2015-08-28 19:07:29.098 soulbeats[13709:3307] Discovered speaker with id 7782687177520836128
2015-08-28 19:07:29.250 soulbeats[13709:3307] Added speakerID: 7782687177520836128 to AllSpeakersIDList
2015-08-28 19:07:29.332 soulbeats[13709:3307] Old speaker info is null
2015-08-28 19:07:29.380 soulbeats[13709:3307] <MultiroomPlay: 0x1460e920>
2015-08-28 19:07:29.394 soulbeats[13709:3307] Value of Groupinfo: <GroupInfo: 0x1589aad0>
2015-08-28 19:07:29.400 soulbeats[13709:3307] HandleGrouping: added new member with id 7782687177520836128 temp group with ip 239.11.11.12
在适当的初始化方法中添加以下行
_IP_GroupInfo_Map = [NSMutableDictionary dictionary];
原来你的程序是多线程的。用 @synchronized
包围您的代码并获得预期的输出显示了这一点。
@synchronized
导致块以原子方式执行。在两个线程可以输入您的代码之前,它们都发现您的字典为 nil 并且都实例化了它,现在两个(或更多)线程各自在同步块的顶部等待,直到其他线程退出。
但是,您不应只接受“它现在可以工作”,您应该尝试找出为什么您不认为它是多线程的!
(此问题的部分内容已在 chat 中讨论)。