Changeset 23524
- Timestamp:
- 05/20/2008 07:55:56 PM (7 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Source/AdiumContactPropertiesObserverManager.h
r23220 r23524 12 12 @interface AdiumContactPropertiesObserverManager : AIObject { 13 13 //Status and Attribute updates 14 NSMutableSet *contactObservers; 14 NSMutableSet *contactObservers; 15 NSMutableSet *removedContactObservers; 15 16 NSTimer *delayedUpdateTimer; 16 17 int delayedStatusChanges; … … 20 21 21 22 BOOL updatesAreDelayed; 23 24 BOOL informingObservers; 22 25 /* Only the contact controller can speak to us directly, and it's allowed to access these ivars */ 23 26 @public trunk/Source/AdiumContactPropertiesObserverManager.m
r23227 r23524 249 249 #endif 250 250 [contactObservers removeObject:[NSValue valueWithNonretainedObject:inObserver]]; 251 252 /* If we're in the middle of informing observers, we need to note this now-removed observer 253 * so that we don't attempt to message it during this iteration. 254 */ 255 if (informingObservers) { 256 if (!removedContactObservers) removedContactObservers = [[NSMutableSet alloc] init]; 257 [removedContactObservers addObject:[NSValue valueWithNonretainedObject:inObserver]]; 258 } 251 259 } 252 260 … … 323 331 NSValue *observerValue; 324 332 333 informingObservers = YES; 334 325 335 //Let our observers know 326 enumerator = [ contactObserversobjectEnumerator];336 enumerator = [[[contactObservers copy] autorelease] objectEnumerator]; 327 337 while ((observerValue = [enumerator nextObject])) { 328 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];329 338 id <AIListObjectObserver> observer; 330 339 NSSet *newKeys; 340 341 /* Skip any observer which has been removed while we were iterating over observers, 342 * as we don't retain observers and therefore risk messaging a released object. 343 */ 344 if (removedContactObservers && [removedContactObservers containsObject:observerValue]) 345 continue; 331 346 332 347 observer = [observerValue nonretainedObjectValue]; … … 341 356 [attrChange unionSet:newKeys]; 342 357 } 343 [pool release];344 358 } 345 359 //Send out the notification for other observers … … 349 363 forKey:@"Keys"] : nil)]; 350 364 365 informingObservers = NO; 366 367 //If we removed any observers while informing them, we don't need that information any more 368 if (removedContactObservers) { 369 [removedContactObservers release]; removedContactObservers = nil; 370 } 371 351 372 return [attrChange autorelease]; 352 373 } … … 355 376 - (void)_updateAllAttributesOfObject:(AIListObject *)inObject 356 377 { 357 NSEnumerator *enumerator = [ contactObserversobjectEnumerator];378 NSEnumerator *enumerator = [[[contactObservers copy] autorelease] objectEnumerator]; 358 379 NSValue *observerValue; 359 360 while ((observerValue = [enumerator nextObject])) { 380 381 informingObservers = YES; 382 383 while ((observerValue = [enumerator nextObject])) { 384 /* Skip any observer which has been removed while we were iterating over observers, 385 * as we don't retain observers and therefore risk messaging a released object. 386 */ 387 if (removedContactObservers && [removedContactObservers containsObject:observerValue]) 388 continue; 389 361 390 id <AIListObjectObserver> observer = [observerValue nonretainedObjectValue]; 362 391 363 392 [observer updateListObject:inObject keys:nil silent:YES]; 364 393 } 394 395 informingObservers = NO; 365 396 } 366 397