@@ -1010,7 +1010,7 @@ -(void) disconnectWithStreamError:(MLXMLNode* _Nullable) streamError andExplicit
10101010
10111011 //reset smacks state to sane values (this can be done even if smacks is not supported)
10121012 [self initSM3];
1013- self.unAckedStanzas = stanzas;
1013+ [ self replaceUnackedStanzasWith: stanzas] ;
10141014
10151015 //inform all old iq handlers of invalidation and clear _iqHandlers dictionary afterwards
10161016 @synchronized(self->_iqHandlers) {
@@ -1142,7 +1142,7 @@ -(void) disconnectWithStreamError:(MLXMLNode* _Nullable) streamError andExplicit
11421142
11431143 //reset smacks state to sane values (this can be done even if smacks is not supported)
11441144 [self initSM3];
1145- self.unAckedStanzas = stanzas;
1145+ [ self replaceUnackedStanzasWith: stanzas] ;
11461146
11471147 //inform all old iq handlers of invalidation and clear _iqHandlers dictionary afterwards
11481148 @synchronized(self->_iqHandlers) {
@@ -1670,7 +1670,7 @@ -(void) resendUnackedStanzas
16701670 self.lastOutboundStanza = [NSNumber numberWithInteger:[self.lastOutboundStanza integerValue] - [self.unAckedStanzas count]];
16711671 //Send appends to the unacked stanzas. Not removing it now will create an infinite loop.
16721672 //It may also result in mutation on iteration
1673- [self.unAckedStanzas removeAllObjects ];
1673+ [self replaceUnackedStanzasWith:[NSMutableArray new] ];
16741674 for(NSDictionary* dic in sendCopy)
16751675 [self send:(XMPPStanza*)[dic objectForKey:kStanza]];
16761676 DDLogInfo(@"Done resending unacked stanzas...");
@@ -1804,7 +1804,7 @@ -(BOOL) removeAckedStanzasFromQueue:(NSNumber*) hvalue
18041804 }
18051805
18061806 [iterationArray removeObjectsInArray:discard];
1807- self.unAckedStanzas = iterationArray;
1807+ [ self replaceUnackedStanzasWith: iterationArray] ;
18081808
18091809 //persist these changes (but only if we actually made some changes)
18101810 if([discard count])
@@ -3843,7 +3843,7 @@ -(void) realReadState
38433843 self.lastOutboundStanza = [dic objectForKey:@"lastOutboundStanza"];
38443844 DDLogError(@"Collecting stanzas...");
38453845 NSArray* stanzas = [dic objectForKey:@"unAckedStanzas"];
3846- self.unAckedStanzas = [stanzas mutableCopy];
3846+ [ self replaceUnackedStanzasWith: [stanzas mutableCopy] ];
38473847 DDLogError(@"Done collecting stanzas...");
38483848 self.streamID = [dic objectForKey:@"streamID"];
38493849 if([dic objectForKey:@"isDoingFullReconnect"])
@@ -4115,14 +4115,32 @@ -(void) initSM3
41154115 self.lastHandledInboundStanza = [NSNumber numberWithInteger:0];
41164116 self.lastHandledOutboundStanza = [NSNumber numberWithInteger:0];
41174117 self.lastOutboundStanza = [NSNumber numberWithInteger:0];
4118- self.unAckedStanzas = [NSMutableArray new];
4118+ [ self replaceUnackedStanzasWith: [NSMutableArray new] ];
41194119 self.streamID = nil;
41204120 _smacksAckHandler = [NSMutableArray new];
41214121 DDLogDebug(@"initSM3 done");
41224122 }
41234123 DDLogVerbose(@"After @synchronized of _stateLockObject...");
41244124}
41254125
4126+ -(NSMutableArray*) replaceUnackedStanzasWith:(NSMutableArray*) newUnackedStanzas
4127+ {
4128+ @synchronized(_stateLockObject) {
4129+ //this might take a long time since it throws away all self.unAckedStanzas and thus calls dealloc on each of them in each nesting level
4130+ //--> move deallocation into a background thread
4131+ NSMutableArray* __block oldUnacked = self.unAckedStanzas;
4132+ self.unAckedStanzas = newUnackedStanzas;
4133+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
4134+ DDLogVerbose(@"Sleeping 500ms before throwing away old unAckedStanzas...");
4135+ [NSThread sleepForTimeInterval:0.500];
4136+ DDLogVerbose(@"Now throwing away old unAckedStanzas...");
4137+ oldUnacked = nil;
4138+ DDLogVerbose(@"All old unAckedStanzas successfully deallocated now...");
4139+ });
4140+ }
4141+ return newUnackedStanzas;
4142+ }
4143+
41264144-(void) bindResource:(NSString*) resource
41274145{
41284146 if(resource == nil)
0 commit comments