我试图了解ARC和NSHashTable weakObjectsHashTable的工作原理。我添加到哈希表的对象应该被删除/归零,或者一旦对象被释放后它们变成了什么。下面的NSLog中的代码示例显示该对象仍然存在于哈希表中。我做错了什么?
#import <Foundation/Foundation.h>
int main(int argc, char *argv[])
{
@autoreleasepool
{
NSHashTable *hashTable = [NSHashTable weakObjectsHashTable];
@autoreleasepool
{
NSString *str = @"Hello World!";
[hashTable addObject:str];
str = nil;
}
NSLog(@"hashTable:%@", [hashTable allObjects]);
// prints: hashTable:("Hello World!") – but should be empty?
}
}
答案 0 :(得分:1)
要指定nil对象,它不会影响结果。 NSString * str = @&#34; Hello World!&#34 ;;对象引用并不弱! Apple的文档说:如果在这样的哈希表中没有对对象的强引用,那么这些对象将被释放。
答案 1 :(得分:1)
尝试使用OS X控制台应用程序的这段代码:
//
// 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;
}
你应该看到hashmap确实是空的,对象在for
循环内被正确销毁,其中强引用被放弃。但问题在于.count
属性 - 它存在,告诉我有条目,尽管allObjects
没有返回。
答案 2 :(得分:0)
正如文件所说:
主要选择是提供&#34;弱&#34;自动删除的引用,但在将来的某个无限期点。
因此,自动删除的要点是未知的,并且无法保证在下一个运行循环中将其删除,因此您无法依赖AutoReleasePool
。