2011-06-06 58 views
3

我目前正在努力与我的应用程序,藐视(我的)逻辑核心数据问题。我确信我做错了什么,但看不到。iPhone核心数据 - 获取的管理对象不在设备上发布(罚款在模拟器上)

我在我的核心数据实体上做了一个基本的executeFetchRequest,但是返回的管理对象数组似乎从未在iPhone上运行时发布,在模拟器下它的工作方式与预期完全一样。

尽管使用NSAutoreleasePool来确保内存占用最小化。我也检查过仪器,没有泄漏,只是不断增加内存分配('[NSManagedObject(_PFDynamicAccessorsAndPropertySupport)allocWithEntity:]')。在我的实际应用程序中,这最终导致了didReceiveMemoryWarning调用。

我已经制作了一个最小化的程序,它重现了下面的问题。我曾尝试过各种各样的事情,比如在排出泳池之前断开所有物体,但没有任何快乐。如果我提供了一个NSError指针,则返回错误。没有后台线程正在运行。

#import <mach/mach.h> 
#import <mach/mach_host.h> 

+(natural_t) get_free_memory { 
    mach_port_t host_port; 
    mach_msg_type_number_t host_size; 
    vm_size_t pagesize; 
    host_port = mach_host_self(); 
    host_size = sizeof(vm_statistics_data_t)/sizeof(integer_t); 
    host_page_size(host_port, &pagesize); 
    vm_statistics_data_t vm_stat; 
    if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { 
     NSLog(@"Failed to fetch vm statistics"); 
     return 0; 
    } 
    /* Stats in bytes */ 
    natural_t mem_free = vm_stat.free_count * pagesize; 
    return mem_free; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Set up the edit and add buttons. 
    self.navigationItem.leftBarButtonItem = self.editButtonItem; 

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject)]; 
    self.navigationItem.rightBarButtonItem = addButton; 
    [addButton release]; 

    // Obtain the Managed Object Context 
    NSManagedObjectContext *context = [(id)[[UIApplication sharedApplication] delegate] managedObjectContext]; 

    // Check the free memory before we start 
    NSLog(@"INITIAL FREEMEM: %d", [RootViewController get_free_memory]); 

    // Loop around a few times 
    for(int i=0; i<20; i++) { 

     // Create an autorelease pool just for this loop 
     NSAutoreleasePool *looppool = [[NSAutoreleasePool alloc] init]; 

     // Check the free memory each time around the loop 
     NSLog(@"FREEMEM: %d", [RootViewController get_free_memory]); 

     // Create a minimal request 
     NSEntityDescription *entityDescription = [NSEntityDescription             
               entityForName:@"TestEntity" inManagedObjectContext:context];   
     NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
     [request setEntity:entityDescription]; 

     // Perform the fetch 
     NSArray *array = [context executeFetchRequest:request error:nil];   
     [request release]; 

     // Drain the pool - should release the fetched managed objects? 
     [looppool drain]; 

    } 

    // Check the free menory at the end 
    NSLog(@"FINAL FREEMEM: %d", [RootViewController get_free_memory]); 

} 

当我运行在模拟器上我得到下面的输出(这看起来合理的,我):

2011-06-06 09:50:28.123 renniksoft[937:207] INITIAL FREEMEM: 14782464 
2011-06-06 09:50:28.128 renniksoft[937:207] FREEMEM: 14807040 
2011-06-06 09:50:28.135 renniksoft[937:207] FREEMEM: 14831616 
2011-06-06 09:50:28.139 renniksoft[937:207] FREEMEM: 14852096 
2011-06-06 09:50:28.142 renniksoft[937:207] FREEMEM: 14872576 
2011-06-06 09:50:28.146 renniksoft[937:207] FREEMEM: 14897152 
2011-06-06 09:50:28.149 renniksoft[937:207] FREEMEM: 14917632 
2011-06-06 09:50:28.153 renniksoft[937:207] FREEMEM: 14938112 
2011-06-06 09:50:28.158 renniksoft[937:207] FREEMEM: 14962688 
2011-06-06 09:50:28.161 renniksoft[937:207] FREEMEM: 14983168 
2011-06-06 09:50:28.165 renniksoft[937:207] FREEMEM: 14741504 
2011-06-06 09:50:28.168 renniksoft[937:207] FREEMEM: 14770176 
2011-06-06 09:50:28.174 renniksoft[937:207] FREEMEM: 14790656 
2011-06-06 09:50:28.177 renniksoft[937:207] FREEMEM: 14811136 
2011-06-06 09:50:28.182 renniksoft[937:207] FREEMEM: 14831616 
2011-06-06 09:50:28.186 renniksoft[937:207] FREEMEM: 14589952 
2011-06-06 09:50:28.189 renniksoft[937:207] FREEMEM: 14610432 
2011-06-06 09:50:28.192 renniksoft[937:207] FREEMEM: 14630912 
2011-06-06 09:50:28.194 renniksoft[937:207] FREEMEM: 14651392 
2011-06-06 09:50:28.197 renniksoft[937:207] FREEMEM: 14671872 
2011-06-06 09:50:28.200 renniksoft[937:207] FREEMEM: 14692352 
2011-06-06 09:50:28.203 renniksoft[937:207] FINAL FREEMEM: 14716928 

然而,当我在实际的iPhone 4运行(4.3.3 )我得到以下结果:

2011-06-06 09:55:54.341 renniksoft[4727:707] INITIAL FREEMEM: 267927552 
2011-06-06 09:55:54.348 renniksoft[4727:707] FREEMEM: 267952128 
2011-06-06 09:55:54.702 renniksoft[4727:707] FREEMEM: 265818112 
2011-06-06 09:55:55.214 renniksoft[4727:707] FREEMEM: 265355264 
2011-06-06 09:55:55.714 renniksoft[4727:707] FREEMEM: 264892416 
2011-06-06 09:55:56.215 renniksoft[4727:707] FREEMEM: 264441856 
2011-06-06 09:55:56.713 renniksoft[4727:707] FREEMEM: 263979008 
2011-06-06 09:55:57.226 renniksoft[4727:707] FREEMEM: 264089600 
2011-06-06 09:55:57.721 renniksoft[4727:707] FREEMEM: 263630848 
2011-06-06 09:55:58.226 renniksoft[4727:707] FREEMEM: 263168000 
2011-06-06 09:55:58.726 renniksoft[4727:707] FREEMEM: 262705152 
2011-06-06 09:55:59.242 renniksoft[4727:707] FREEMEM: 262852608 
2011-06-06 09:55:59.737 renniksoft[4727:707] FREEMEM: 262389760 
2011-06-06 09:56:00.243 renniksoft[4727:707] FREEMEM: 261931008 
2011-06-06 09:56:00.751 renniksoft[4727:707] FREEMEM: 261992448 
2011-06-06 09:56:01.280 renniksoft[4727:707] FREEMEM: 261574656 
2011-06-06 09:56:01.774 renniksoft[4727:707] FREEMEM: 261148672 
2011-06-06 09:56:02.290 renniksoft[4727:707] FREEMEM: 260755456 
2011-06-06 09:56:02.820 renniksoft[4727:707] FREEMEM: 260837376 
2011-06-06 09:56:03.334 renniksoft[4727:707] FREEMEM: 260395008 
2011-06-06 09:56:03.825 renniksoft[4727:707] FREEMEM: 259932160 
2011-06-06 09:56:04.346 renniksoft[4727:707] FINAL FREEMEM: 259555328 

可用内存的数量每次循环都会减少,与获取的托管对象成比例如果我获取的对象数量是对象的两倍,那么可用内存会减少一倍 - 所以我相当确信它是未被释放的托管对象。

请注意,正在提取的实体是非常基本的,只有两个属性,一个字符串和一个16位整数。在上面的例子中有1000个被抓取。我用来生成它们的代码如下:

// Create test entities 
for(int i=0; i<1000; i++) { 
    id entity = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity" inManagedObjectContext:context]; 
    [entity setValue:[NSString stringWithFormat:@"%d",i] forKey:@"name"]; 
    [entity setValue:[NSNumber numberWithInt:i] forKey:@"value"]; 
} 
if (![context save:nil]) { 
    NSLog(@"Couldn't save"); 
} 

如果任何人都可以向我解释发生了什么,我会非常感激!这个问题是唯一一个阻止我的应用程序发布。它在模拟器上运行非常漂亮!

请让我知道,如果有任何更多的信息,我可以提供。

+0

只是好奇,是否有人设法使用上述代码重现此问题,还是只是我? – cliveski 2011-06-07 13:28:15

回答

1

卫生署!这是我看起来愚蠢的一点!

我把'NSZombieEnabled'设置为YES,这意味着获取的数据没有被发布!这一切都工作正常没有:-)

0

我现在没有可以测试的MacOs设备。但我看到你没有注册NSFetchRequest进行autorelease。

我会尝试这个办法:

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
+0

只是注意到你在请求实例上调用release。 – 2011-06-06 10:49:53

+0

是的,只是想尽量减少autorelease池的使用。 – cliveski 2011-06-06 11:57:17

相关问题