Adium

Changeset 23109

Show
Ignore:
Timestamp:
04/12/2008 01:18:59 PM (7 months ago)
Author:
evands
Message:

Added debug build monitoring of whether AIListObjectObservers are properly unregistering themselves. This should let us figure out which object is failing to do so and therefore causing the crash in #9425, which occurs very intermittently. Refs #9425.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Source/AIContactController.h

    r22859 r23109  
    2828#define PREF_GROUP_CONTACT_LIST_DISPLAY @"Contact List Display" 
    2929 
     30#ifdef DEBUG_BUILD 
     31        #define CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG        TRUE 
     32#endif 
     33 
    3034@class AISortController, AdiumAuthorization, AIContactHidingController; 
    3135 
     
    4852         
    4953        //Status and Attribute updates 
    50     NSMutableSet                        *contactObservers; 
     54#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
     55    NSMutableArray                      *contactObservers; 
     56#else 
     57    NSMutableSet                        *contactObservers;       
     58#endif 
    5159    NSTimer                                     *delayedUpdateTimer; 
    5260    int                                         delayedStatusChanges; 
  • trunk/Source/AIContactController.m

    r23023 r23109  
    7373#define UID_KEY                                                 @"UID" 
    7474 
     75#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
     76        static BOOL unregisterListObjectObserverCalled = NO; 
     77#endif 
     78 
    7579@interface AIContactController (PRIVATE) 
    7680- (AIListGroup *)processGetGroupNamed:(NSString *)serverGroup; 
     
    122126        if ((self = [super init])) { 
    123127                // 
     128#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
     129                contactObservers = [[NSMutableArray alloc] init]; 
     130#else 
    124131                contactObservers = [[NSMutableSet alloc] init]; 
     132#endif 
    125133                sortControllerArray = [[NSMutableArray alloc] init]; 
    126134                activeSortController = nil; 
     
    11611169        //Create a new metaContact is we didn't find one. 
    11621170        if (!metaContact) { 
     1171                AILogWithSignature(@"New metacontact to group %@ on %@", UIDsArray, servicesArray); 
    11631172                metaContact = [self metaContactWithObjectID:nil]; 
    11641173        } 
     
    12091218        //Create a new metaContact is we didn't find one. 
    12101219        if (!metaContact) { 
     1220                AILogWithSignature(@"New metacontact to group %@", contactsToGroupArray); 
    12111221                metaContact = [self metaContactWithObjectID:nil]; 
    12121222        } 
     
    14241434- (void)registerListObjectObserver:(id <AIListObjectObserver>)inObserver 
    14251435{ 
     1436        //Add the observer 
     1437#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
    14261438        AILogWithSignature(@"%@", inObserver); 
    1427  
    1428         //Add the observer 
     1439    [contactObservers addObject:inObserver]; 
     1440#else 
    14291441    [contactObservers addObject:[NSValue valueWithNonretainedObject:inObserver]]; 
     1442#endif 
    14301443         
    14311444    //Let the new observer process all existing objects 
     
    14351448- (void)unregisterListObjectObserver:(id)inObserver 
    14361449{ 
     1450#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
    14371451        AILogWithSignature(@"%@", inObserver); 
    1438  
     1452    [contactObservers removeObjectIdenticalTo:inObserver]; 
     1453        unregisterListObjectObserverCalled = YES; 
     1454#else 
    14391455    [contactObservers removeObject:[NSValue valueWithNonretainedObject:inObserver]]; 
     1456#endif 
    14401457} 
    14411458 
     
    15081525{ 
    15091526        NSMutableSet    *attrChange = nil; 
     1527 
     1528#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
     1529        NSObject <AIListObjectObserver> *observer; 
     1530         
     1531        //Let our observers know 
     1532        int i; 
     1533        for (i = 0; i < [contactObservers count]; i++) { 
     1534                NSAutoreleasePool       *pool = [[NSAutoreleasePool alloc] init]; 
     1535                NSSet                           *newKeys; 
     1536 
     1537                observer = [contactObservers objectAtIndex:i]; 
     1538 
     1539                if ([observer retainCount] == 1) { 
     1540                        NSString *observerDescription = [observer description]; 
     1541 
     1542                        /* This observer is fully released except for our retention (contactObservers plus its copy), which wouldn't happen without  
     1543                         * CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG defined.  That -might- be an error... except that it 
     1544                         * might remove itself as an observer in its dealloc method, which is fine if it actually happens. 
     1545                         */ 
     1546                        unregisterListObjectObserverCalled = NO; 
     1547                        [contactObservers removeObjectIdenticalTo:observer]; 
     1548                         
     1549                        //observer will have deallocated.  It should have called removeContactObserver in the process. If it didn't, that's bad. 
     1550                        if (!unregisterListObjectObserverCalled) { 
     1551                                AILogWithSignature(@"%@ failed at removing itself as a contact observer! This would be fatal in a release build!", observerDescription); 
     1552                                NSLog(@"%@ failed at removing itself as a contact observer! This would be fatal in a release build!", observerDescription); 
     1553                                NSAssert1(FALSE, @"%@ failed at removing itself as a contact observer! This would be fatal in a release build!", observerDescription); 
     1554                        } else { 
     1555                                AILogWithSignature(@"All is well after the dealloc of %@", observerDescription); 
     1556                        } 
     1557                } else { 
     1558                        if ((newKeys = [observer updateListObject:inObject keys:modifiedKeys silent:silent])) { 
     1559                                if (!attrChange) attrChange = [[NSMutableSet alloc] init]; 
     1560                                [attrChange unionSet:newKeys]; 
     1561                        } 
     1562                } 
     1563                [pool release]; 
     1564        }        
     1565#else 
    15101566        NSEnumerator    *enumerator; 
    15111567        NSValue                 *observerValue; 
     
    15251581                [pool release]; 
    15261582        } 
    1527          
     1583#endif 
    15281584        //Send out the notification for other observers 
    15291585        [[adium notificationCenter] postNotificationName:ListObject_StatusChanged 
     
    15391595{ 
    15401596        NSEnumerator    *enumerator = [contactObservers objectEnumerator]; 
     1597#ifdef CONTACT_OBSERVER_MEMORY_MANAGEMENT_DEBUG 
     1598        id <AIListObjectObserver> observer; 
     1599         
     1600        while ((observer = [enumerator nextObject])) {           
     1601                [observer updateListObject:inObject keys:nil silent:YES]; 
     1602        } 
     1603#else 
    15411604        NSValue                 *observerValue; 
    15421605         
     
    15461609                [observer updateListObject:inObject keys:nil silent:YES]; 
    15471610        } 
     1611#endif   
    15481612} 
    15491613