[英]Leaking Memory on iPhone :(
我是C,Obj-C和iPhone的初學者,我正在嘗試掌握很多使用的術語。 我希望你們中的一個可以幫助解決我幾天來一直在苦苦掙扎的問題。
我下面的代碼是一種調用包含搜索字段和表的筆尖的方法。 該表是從下面為“ theList”創建的數組的搜索中填充的。 使用'Instruments',我得到了泄漏:NSDictionary * theItem = [NSDictionary dictionaryWithObjectsAndKeys:clientName,@“ Name”,clientId,@“ Id”,nil]; ,但我不知道為什么:(
我知道這可能是一個很難回答的問題,但是如果有任何幫助的話!
- (void)editClient:(id)sender {
if (pickList == nil) {
pickList = [[PickFromListViewController alloc] initWithNibName:@"PickList" bundle:nil];
}
TimeLogAppDelegate *appDelegate = (TimeLogAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *theList = [[NSMutableArray alloc] init];
int i;
for (i=0;i < [appDelegate.clients count];i++) {
Client *thisClient = [appDelegate.clients objectAtIndex:i];
NSString *clientName = [[NSString alloc] initWithString: thisClient.clientsName];
NSNumber *clientId = [[NSNumber alloc] init];
clientId = [NSNumber numberWithInt:thisClient.clientsId];
NSDictionary *theItem = [NSDictionary dictionaryWithObjectsAndKeys:clientName,@"Name",clientId,@"Id",nil];
[theList addObject:theItem];
theItem = nil;
[clientName release];
[clientId release];
}
[pickList createSearchItems:theList :NSLocalizedString(@"Client",nil)];
[theList release];
appDelegate.returningID = [NSNumber numberWithInt: projectsClientsId];
[self.navigationController pushViewController:pickList animated:YES];
}
提前致謝!
這將返回分配的NSNumber實例。
NSNumber *clientId = [[NSNumber alloc] init];
此行用另一個NSNumber實例覆蓋上述clientId,numberWithInt返回自動釋放的對象,因為尚未為其分配內存,因此不應該調用release,它將自動釋放。
clientId = [NSNumber numberWithInt:thisClient.clientsId];
您正在調用clientId上的release,因此會遇到內存問題。 要解決此問題,請刪除上面的第一行,在這種情況下,第一行是無用的,並將第二行更新為:
NSNumber * clientId = [NSNumber numberWithInt:thisClient.clientsId];
然后刪除:
[clientId release]
因為clientId將自動釋放。
編輯 :仍然有問題...我不確定如何在應用程序委托中操作客戶端,否則代碼應該可以正常工作,我創建了一個小示例,省略了我看不到的部分(應用程序委托和客戶端):
//命令行實用程序-基礎工具項目:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray * theList = [[NSMutableArray alloc] init];
int i = 0;
for (i = 0; i < 10; ++i)
{
NSString * clientName = [NSString stringWithString:@"client"]; //no need to release
NSNumber * clientId = [NSNumber numberWithInt:i];
NSDictionary * theItem = [NSDictionary dictionaryWithObjectsAndKeys:
clientName, @"name",
clientId, @"id",
nil];
[theList addObject:theItem];
}
for (id item in theList) for (id key in item) NSLog(@"%@ - %@", key, [item objectForKey:key]);
[theList release];
[pool drain];
return 0;
}
您正在使用[[NSNumber alloc] init]
創建clientID,然后立即使用自動釋放的NSNumber實例[NSNumber numberWithInt]
覆蓋它,然后稍后在代碼中釋放它,您不應該這樣做。 擺脫[[NSNumber alloc] init]
行和[clientId release]
行,這應該可以對其進行一些修復。
除了NSNumber明顯泄漏外,還有一些其他我可能會解決的問題可能會有所幫助。 大多數代碼都是次要的,但是以我在Objective-C的經驗來看,更少的代碼==更清晰的代碼,對於Bash或Perl之類的語言而言,情況並非如此。 ;-)
- (void) editClient:(id)sender {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (pickList == nil) {
pickList = [[PickFromListViewController alloc] initWithNibName:@"PickList" bundle:nil];
}
TimeLogAppDelegate *appDelegate = (TimeLogAppDelegate*)[[UIApplication sharedApplication] delegate];
NSMutableArray *searchItems = [NSMutableArray array];
NSMutableDictionary *itemDict = [NSMutableDictionary dictionary];
for (Client *client in appDelegate.clients) {
[itemDict setObject:[client.clientsName copy] forKey:@"Name"];
[itemDict setObject:[NSNumber numberWithInt:client.clientsId] forKey:@"Id"];
[searchItems addObject:[[itemDict copy] autorelease]];
}
[pickList createSearchItems:searchItems :NSLocalizedString(@"Client",nil)];
[self.navigationController pushViewController:pickList animated:YES];
appDelegate.returningID = [NSNumber numberWithInt: projectsClientsId];
[pool drain];
}
有一些讓我懷疑的神秘之處:
-pushViewController:animated:
方法在指定新的選擇列表后正確釋放現有的選擇列表。 appDelegate.returningID
來調用setter的returningID
屬性。 確保屬性根據需要保留或復制NSNumber
。 即使在Instruments中,內存泄漏也很難跟蹤,並且您經常會發現它看起來像是基礎類(例如NSDictionary
)正在像篩子一樣泄漏,但是我一直能夠將其追溯到我的代碼。 :-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.