我对iphone中处理内存管理的方式有问题。请帮助我..我的想法已经用完了...我试着用下面的方法玩,但是当我试图分配时它开始泄漏对象的字符串(例如为sid,first_name等分配)..我无法弄清楚如何做...这是我将从服务获取所有联系人并将其插入数据库的方法。它消耗了更多的内存,我通过在iphone上运行分配工具和iphone崩溃上的应用程序想出来了...请帮助我们..有什么更好的解决方案..我认为我的应用程序消耗更多内存但不确定在哪里调查它..如果不清楚,我可以发布任何代码。谢谢你们!
- (void) get_entry_listHandler: (id) value{
NSString *salutation,*sugar_id,*first_name,*last_name,*title1,*department,*phone_home,*phone_mobile,*phone_work,*phone_other,*phone_fax,*assistant,*assistant_phone,*primary_address_street,*primary_address_city,*primary_address_state,*primary_address_postalcode,*custom;
NSString *primary_address_country,*alt_address_street,*alt_address_city,*alt_address_state,*alt_address_postalcode,*alt_address_country,*date_entered,*date_modified,*deleted,*do_not_call,*birthdate,*lead_source,*description,*email1,*email2,*account_name,*account_id,*id1;
// Handle errors
if([value isKindOfClass:[NSError class]]) {
NSLog(@"%@", value);
return;
}
// Handle faults
if([value isKindOfClass:[SoapFault class]]) {
NSLog(@"%@", value);
return;
}
// Do something with the SCRMget_entry_list_result* result
SCRMget_entry_list_result* result = (SCRMget_entry_list_result*)value;
//NSLog(@"get_entry_list returned the value: %@", result);
//NSLog(@"%@", result.entry_list);
NSLog(@"%@", result.error);
SCRMsugarsoap* service = [[SCRMsugarsoap alloc] initWithUrl:serverURL];
SCRMentry_value* entry;
for(NSString * myStr in result.entry_list) {
entry = (SCRMentry_value*)myStr;
//NSLog(@"1st %@",entry.name_value_list);
//NSLog(@"1st %@",entry.id);
//NSLog(@"1st %@",entry.module_name);
for(NSString * myStr1 in entry.name_value_list) {
SCRMname_value* value1 = (SCRMname_value*)myStr1;
if ([value1.name isEqualToString:@"id"])
sugar_id = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"salutation"])
salutation = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"first_name"])
first_name = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"last_name"])
last_name = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"title"])
title1 = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"department"])
department = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"phone_home"])
phone_home = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"phone_mobile"])
phone_mobile = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"phone_work"])
phone_work = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"phone_other"])
phone_other = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"phone_fax"])
phone_fax = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"assistant"])
assistant = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"assistant_phone"])
assistant_phone = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"primary_address_street"])
primary_address_street = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"primary_address_city"])
primary_address_city = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"primary_address_state"])
primary_address_state = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"primary_address_postalcode"])
primary_address_postalcode = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"primary_address_country"])
primary_address_country = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"alt_address_street"])
alt_address_street = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"alt_address_city"])
alt_address_city = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"alt_address_state"])
alt_address_state = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"alt_address_postalcode"])
alt_address_postalcode = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"alt_address_country"])
alt_address_country = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"date_entered"])
date_entered = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"date_modified"])
date_modified = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"deleted"])
deleted = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"do_not_call"])
do_not_call = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"birthdate"])
birthdate = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"lead_source"])
lead_source = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"description"])
description = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"email1"])
email1 = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"email2"])
email2 = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"account_name"])
account_name = [[NSString alloc] initWithFormat: @"%@",value1.value];
else if ([value1.name isEqualToString:@"account_id"])
account_id = [[NSString alloc] initWithFormat: @"%@",value1.value];
else
custom = [[NSString alloc] initWithFormat: @"%@",value1.value];
}
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateFormat:@"yyy-MM-dd HH:mm:ss"];
NSDate *date_moded = [df dateFromString:date_modified];
NSDate *lastSync = [df dateFromString:lastSyncTime];
NSDate *date_enter = [df dateFromString:date_entered];
[df release];
if ([[date_moded laterDate:lastSync]isEqualToDate:date_moded] && lastSyncTime != nil && [date_enter isEqualToDate:date_moded])
id1 = [[NSString alloc]initWithFormat:@"%d",primaryKeyCount];
else if ([[date_moded laterDate:lastSync]isEqualToDate:date_moded] && lastSyncTime != nil )
id1 = [db getPrimaryKey:sugar_id];
else
id1 = [[NSString alloc]initWithFormat:@"%d",primaryKeyCount];
[db insertRecordIntoTableNamed: @"Contacts" withField1: @"id" field1Value: id1 andField2: @"sugar_id" field2Value: sugar_id
andField3: @"salutation" field3Value: salutation andField4: @"first_name" field4Value: first_name
andField5: @"last_name" field5Value: last_name andField6: @"title" field6Value: title1
andField7: @"department" field7Value: department andField8: @"phone_home" field8Value: phone_home
andField9: @"phone_mobile" field9Value: phone_mobile andField10: @"phone_work" field10Value: phone_work
andField11: @"phone_other" field11Value: phone_other andField12: @"phone_fax" field12Value: phone_fax
andField13: @"assistant" field13Value: assistant andField14: @"assistant_phone" field14Value: assistant_phone
andField15: @"primary_address_street" field15Value: primary_address_street andField16: @"primary_address_city" field16Value: primary_address_city
andField17: @"primary_address_state" field17Value: primary_address_state andField18: @"primary_address_postalcode" field18Value: primary_address_postalcode
andField19: @"primary_address_country" field19Value: primary_address_country andField20: @"alt_address_street" field20Value: alt_address_street
andField21: @"alt_address_city" field21Value: alt_address_city andField22: @"alt_address_state" field22Value: alt_address_state
andField23: @"alt_address_postalcode" field23Value: alt_address_postalcode andField24: @"alt_address_country" field24Value: alt_address_country
andField25: @"date_entered" field25Value: date_entered andField26: @"date_modified" field26Value: date_modified
andField27: @"deleted" field27Value: deleted andField28: @"do_not_call" field28Value: do_not_call
andField29: @"birthdate" field29Value: birthdate andField30: @"lead_source" field30Value: lead_source
andField31: @"description" field31Value: description andField32: @"email1" field32Value: email1
andField33: @"email2" field33Value: email2 andField34: @"account_name" field34Value: account_name
andField35: @"account_id" field35Value: account_id andField36: @"custom" field36Value: custom];
primaryKeyCount++;
currentCount++;
//NSLog(@"%D",i);
}
[salutation release];
[sugar_id release];
[first_name release];
[last_name release];
[title1 release];
[department release];
[phone_home release];
[phone_mobile release];
[phone_work release];
[phone_fax release];
[phone_other release];
[assistant release];
[assistant_phone release];
[primary_address_street release];
[primary_address_city release];
[primary_address_state release];
[primary_address_postalcode release];
[primary_address_country release];
[alt_address_street release];
[alt_address_city release];
[alt_address_state release];
[alt_address_postalcode release];
[alt_address_country release];
[custom release];
[date_entered release];
[deleted release];
[do_not_call release];
[birthdate release];
[lead_source release];
[description release];
[email1 release];
[email2 release];
[account_name release];
[account_id release];
float expected = (float) contactEntries;
float gotSoFar = (float) currentCount;
syncViewController.progressView.progress = ((float)((gotSoFar - 1) / (expected + 1)));
syncViewController.progressLabel.text=[NSString stringWithFormat:@"Syncing %d Contacts",contactEntries];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
integer = [NSNumber numberWithInt:primaryKeyCount];
[defaults setObject:integer forKey:@"primaryKeyCount"];
[defaults synchronize];
moduleViewController.db = db;
int a = result.next_offset;
int b = contactEntries;
while (result.result_count == 20 /*&& result.next_offset < contactEntries*/) {
if ( lastSyncTime == nil) {
[service get_entry_list:self action:@selector(get_entry_listHandler:) session:sessionId module_name: @"Contacts" query: @"" order_by: @"" offset: result.next_offset select_fields: [[[SCRMselect_fields alloc] init]autorelease] max_results: contactEntries deleted: 0];
[service release];
return;
//break;
}
else {
[service get_entry_list:self action:@selector(get_entry_listHandler:) session:sessionId module_name: @"Contacts" query: finalQuery order_by: @"" offset: result.next_offset select_fields: [[[SCRMselect_fields alloc] init]autorelease] max_results: contactEntries deleted: 0];
[service release];
return;
//break;
}
}
if (a >= b ) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[settingsViewController.navigationController pushViewController:moduleViewController animated:YES];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:@"reset"];
[defaults synchronize];
[finalQuery release];
}
/*else if (a >= b && syncing == YES) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[moduleViewController reload];
}*/
[service release];
[id1 release];
}
修改
我摆脱了所有泄漏,但任何人都可以告诉我如何检查iphone中的对象分配工具..请看下面的截图..我的应用程序崩溃一旦它加载所有4200个联系人和联系人是从未显示在表格视图上。可能是什么问题..我确保将我的联系人保存到数据库的地方是无泄漏的..在下面的屏幕截图中,我应该找到什么......是它总分配或生活..请让我知道伙计们......我已经筋疲力尽了......感谢你们的时间..
答案 0 :(得分:3)
你应该把[string release]; for(NSString * myStr in result.entry_list)循环中的行。每次调用alloc时,都必须有相应的释放调用。
更好的方法是使用[NSString stringWithFormat:]而不是[[NSString alloc] initWithFormat:],这样就不需要手动释放它们了。
我的应用一旦加载就崩溃了 4200个联系人和联系人 从未显示在表格视图上,无论何时显示在表格视图
上
4200个联系人使你的循环“大而紧”。正如taskinoor所建议的那样,你可以为每一个循环创建和排出一个NSAutoreleasePool,以减少内存占用量。例如:
int counter = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (...) {
if (++counter == 100) {
counter = 0;
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
//busy working...
}
[pool release];
如果响应系统事件需要很长时间,您的应用也可能被iOS终止。这种机制被称为看门狗超时。在这种情况下,您将在崩溃报告中找到异常代码0x8badf00d。您可能希望将工作分成更小的批次或使用辅助线程,以便主线程不会忙碌太长时间。
答案 1 :(得分:2)
这是一个很长的代码,可能是我错了。但我的猜测就是这个。
for(NSString * myStr in result.entry_list) { // lots of alloc } // releases in this point
现在,如果你在result.entry_list中有多个条目(我猜你有),你不是在泄漏字符串吗?假设您在第一次传递中分配了str,而在下一次分配期间在第二次传递中分配了您正在泄漏这个。明白我的观点?
如果这是问题,那么你应该在循环中移动释放调用。
另一种解决方案是,您似乎不需要此范围之外的字符串。那么为什么不使用autorealse方法来创建呢?
str = [NSString stringWithFormat:@"what_you_need"];
您现在无需释放它们。虽然在这种情况下,您应该考虑创建自己的自动释放池,因为数据量可能很大。