8

NSMutableDictionary is still not instantiated and initialized

 2 years ago
source link: https://www.codesd.com/item/nsmutabledictionary-is-still-not-instantiated-and-initialized.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

NSMutableDictionary is still not instantiated and initialized

advertisements

Below is the method being called every time a speaker info is received.

- (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];
        }
    }
}

Now I'll explain a bit about what the code does.

  • Everytime a speaker info is received, it will get the stored GroupInfo obtained with the key, speakerInfo.mGroupIP

  • If groupInfo is nil then simple instantiate a new one and then add the speaker info's ID into groupInfo

  • If it is not then go on and add the speakerInfo into the existing GroupInfo

Ok, here's the problem, take a look at the Log(Please don't mind other Log messages, only the one that starts with "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

As can be seen from above, the groupInfo was instantiated TWICE. You can see the log message "New temp group 239.11.11.12" appeared 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

I don't understand why this is happening. I get the groupInfo object with the same key, which is the ip of the speakerInfo received, 239.11.11.12. So I am expecting that on the first call on this method, the groupInfo should be nil. But after that, since I already added a speakerInfo.mID in it and set it again to the _IP_GroupInfo_Map dictionary, groupInfo shouldn't be nil on next call of this method.

Additional information:

I declare NSMutableDictionary this way:

@property (nonatomic, strong) NSMutableDictionary *IP_GroupInfo_Map;

What can I do to solve this? Please help. Many many thanks.

--------- UPDATE: Added 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

As can be seen, the id is exactly the SAME.

------- ANOTHER UPDATE: Added Code On How Class Is Initialized -------

+ (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;
}

--------- Added Log For Value Of 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


It turns out your program is multithreaded. Surrounding your code with @synchronized and getting the expected output showed this.

The @synchronized causes the block to be executed atomically. Whereas before two threads could enter your code, both find that your dictionary was nil and both instantiate it, now the two (or more) threads each wait at the top of the synchronised block until the other(s) exit.

However, instead of just accepting "it works now", you should try and find out why is multithreaded when you didn't think it was!


(Parts of this issue were discussed in chat).


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK