Try this piece of code for OS X console application:
//
// main.m
//
#import <Foundation/Foundation.h>
uint objectsAlive = 0;
uint totalObjects = 0;
@interface TestObject : NSObject
@end
@implementation TestObject
{
uint myIx;
}
- (id)init
{
// NSAssert([NSThread currentThread] == [NSThread mainThread], @"Not on the main thread");
self = [super init];
if (self)
{
objectsAlive++;
totalObjects++;
myIx = totalObjects;
NSLog(@"Object with id=%u created; alive objects %u", myIx, objectsAlive);
}
return self;
}
- (void)dealloc
{
objectsAlive--;
NSLog(@"Object with id=%u is being destroyed by ARC; alive objects will become %u", myIx,objectsAlive);
}
@end
int main(int argc, const char * argv[]) {
// default global autorelease pool
@autoreleasepool {
NSHashTable * testHashMap = [NSHashTable weakObjectsHashTable];
// weakObjectsHashTable - according to Apple docs, entries are not necessarily purged right away when the weak object is reclaimed, and we can observe this behavior here - some entries stay alive until last autorelease
// comment out the line above and uncomment the line below to observe different behavior with strong references in NSHashTable
// NSHashTable * testHashMap = [[NSHashTable alloc] init];
// nested autoreleasepool to ensure that the objects added to the testHashMap are released by ARC
@autoreleasepool {
for(int i = 0; i < 10;i++) {
TestObject * obj = [[TestObject alloc] init];
[testHashMap addObject: obj];
NSLog(@"Count in hash table inside additions scope is %lu",
(unsigned long)testHashMap.count);
}
NSLog(@"Count in hash table inside @autoreleasepool is %lu",
(unsigned long)testHashMap.count);
NSLog(@"Objects in hash table inside of @autoreleasepool are %@",
testHashMap.allObjects);
NSLog(@"Exiting inner autorelease pool...");
}
// objects in NSHashTable also were released, according to dealloc logs in TestObject, but count is still lagging behind (shows 2)
NSLog(@"Count in hash table outside of @autoreleasepool is %lu",
(unsigned long)testHashMap.count);
// this should indeed show that NSHashTable with weakObjectsHashTable is empty, despite count=2
NSLog(@"Objects in hash table outside of @autoreleasepool are %@",
testHashMap.allObjects);
NSLog(@"Exiting outer autorelease pool, ecpect all objects in strong ref NSHashTable to die...");
}
return 0;
}
You should see that the hashmap indeed is empty and objects get correctly destroyed right inside the for
loop where their strong references are abandoned. But the problem is with .count
property - it lies, telling that there are entries although allObjects
return none.