2013-02-16 57 views
-2

我正在运行此代码以创建一个包含调用者名称的图像,并将其设置为特定联系人,但运行时,我收到内存警告并且它崩溃...在AddressBook上运行一个循环 - 收到内存警告

-(void)RunActionInBlack{ 


//black bg - white text 

ABAddressBookRef addressBook; 
CFErrorRef error = NULL; 

addressBook = ABAddressBookCreate(); 

CFArrayRef array=ABAddressBookCopyArrayOfAllPeople(addressBook); 

ABRecordRef person; 
int len=CFArrayGetCount(array); 

for (int i = 0; i<len; i++){ 
    person = CFArrayGetValueAtIndex(array, i); 
    details.text = [NSString stringWithFormat:@"Done. %d of %d contacts", i+1,len]; 
    [act stopAnimating]; 
    NSString *firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); 

    if (firstName == NULL) { 
     firstName = @""; 
    } 
    if (lastName == NULL) { 
     lastName = @""; 
    } 

    UIImage *im = [self addText:[UIImage imageNamed:@"black.png"] andText:[NSString stringWithFormat:@"%@ %@",firstName, lastName]]; 
    NSData *dataRef = UIImagePNGRepresentation(im); 

    ABPersonSetImageData(person, (CFDataRef)dataRef, &error); 


    [lastName release]; 
    [firstName release]; 
    [dataRef release]; 
    CFRelease(dataRef); 
    [im release]; 
} 
ABAddressBookSave(addressBook, &error); 
CFRelease(array); 
CFRelease(addressBook); 
} 

创建文本:

-(UIImage *)addText:(UIImage *)img andText:(NSString*)txt{ 

UIImageView *imView =[[UIImageView alloc] initWithImage:img ]; 
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, img.size.width, img.size.height)]; 
[tempView addSubview:imView]; 

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, -100, img.size.width, img.size.height)]; 
[label setText:txt]; 
[label setFont:[UIFont boldSystemFontOfSize:160]]; 
[label setTextColor:[UIColor whiteColor]]; 
[label setTextAlignment:UITextAlignmentCenter]; 
[label setBackgroundColor:[UIColor clearColor]]; 
[label setNumberOfLines:10]; 
[tempView addSubview:label]; 

UIGraphicsBeginImageContext(tempView.bounds.size); 
[tempView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
[label release]; 
[tempView release]; 
[imView release]; 
return finalImage; 
} 

我没有任何内存泄漏或东西...

我跑的方法,如:[self performSelectorInBackground:@selector(RunActionInWhite) withObject:nil];

在此先感谢。

+1

它似乎在这段代码中的内存管理有点差。桥接是“CF”引用和Objective C对象之间的巨大混沌......例如, 'dataRef'是** not **'CF'引用,'firstName'和'lastName' **是**'CF'引用。这些微小的东西会导致严重的内存泄漏。 – holex 2013-02-16 20:50:15

回答

2

如果您正在遍历大型数组并获取内存警告,那么您可能正在使用直到退出for循环之后才会释放的资源。 (或者在这种情况下,没有得到释放可言,因为你的应用程序崩溃。)

你想与

for (int i=0; i<max; i++) { 
    @autoreleasepool { 

    } 
} 
+0

我应该在哪里放这个autorelease?顺便说一句,我正在运行这些方法使用:[self performSelectorInBackground:@selector(RunActionInWhite)withObject:nil]; – 2013-02-16 20:54:32

+1

for循环for(){@autoreleasepool {...}} – 2013-02-17 13:26:30

0

来包装你的循环内的代码好像你正在运行内存不足而保留大量无法释放的对象,如addressBook内容,并且您似乎还有一个名为arrayaddressBook的整个副本。

所以,

  • 你真的需要addressBook的副本?尝试摆脱它。
  • 将迭代拆分成较小的部分,将地址簿保存在几十条记录的每个块之后,这应该释放一些内部使用的资源。

接下来,您可以尝试使用仪器分析您的分配,并查看大部分内存。