-3

発信者の名前を含む画像を作成し、特定の連絡先に設定するためにこのコードを実行していますが、実行中に受信メモリの警告が表示されてクラッシュします...

-(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];

前もって感謝します。

4

2 に答える 2

2

for大規模な配列を反復処理しているときにメモリ警告が表示される場合は、ループを終了するまで解放されないリソースを使用している可能性があります。(または、この場合、アプリがクラッシュするため、まったくリリースされません。)

ループ内のコードをラップしたいでしょう

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

    }
}
于 2013-02-16T20:42:13.927 に答える
0

addressBookコンテンツのように解放できない多くのオブジェクトを保持している間にメモリが不足しているように見えます。また、addressBook呼び出されarrayた .

そう、

  • のコピーが本当に必要addressBookですか? それを取り除くようにしてください。
  • 繰り返しを小さな部分に分割し、数十個のレコードのチャンクごとにアドレス帳を保存します。これにより、内部で使用されているリソースが解放されます。

次に、Instruments を使用して割り当てのプロファイリングを試し、何がメモリの大部分を占めているかを確認できます。

于 2013-02-16T20:56:46.913 に答える