2013-02-16 61 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的副本?嘗試擺脫它。
  • 將迭代拆分成較小的部分,將地址簿保存在幾十條記錄的每個塊之後,這應該釋放一些內部使用的資源。

接下來,您可以嘗試使用儀器分析您的分配,並查看大部分內存。