0

PDFファイルを生成するアプリがあります。ユーザーがページを追加できるため、これらの PDF は大きくなる可能性があり、無制限になる可能性があります。十。iPhone 4 ユーザーが PDF 生成段階でクラッシュするという問題があります。一部の調査では、アプリのメモリが不足していることがわかります。iPhone 5 に 50 以上のページを追加した場合、iPhone 4 などでははるかに少なく、予想されるシミュレーターでは問題を再現できません。

PDFを生成してクラッシュするときにアプリがメモリ不足になることを明確にするために。

私はここで調査しました iPhoneアプリはメモリ不足のためにクラッシュしますが、シミュレーターでは正常に動作します

ここでは Quartz PDF APIがメモリ不足のクラッシュを引き起こしています

このメモリ使用量を減らす方法はありますか。私は経験豊富なプログラマーではないので、これを適切に解釈したり修正したりする方法がわかりません。

ここに画像の説明を入力

- (void)generatePdf
{
NSMutableArray *pagesArray = [NSMutableArray array];

if ([self.certificate.certificateType.title isEqualToString:@"Minor Works"]) {
    [pagesArray addObject:[[ICPDFMinorWorksPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFMinorWorksPage2 alloc] initWithCertificate:self.certificate]];

} else if ([self.certificate.certificateType.title isEqualToString:@"EIC"]) {
    [pagesArray addObject:[[ICPDFEICPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICPage2 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICPage3 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICPage4 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICPage5 alloc] initWithCertificate:self.certificate]];
    [self addDistributionBoardsToPagesArray:pagesArray];
    ICPDFEICPageFinal *pageFinal = [[ICPDFEICPageFinal alloc] initWithCertificate:self.certificate];
    pageFinal.pageNumber.text = [NSString stringWithFormat:@"%d", pagesArray.count+1];
    [pagesArray addObject:pageFinal];

} else if ([self.certificate.certificateType.title isEqualToString:@"Domestic EIC"]) {
    [pagesArray addObject:[[ICPDFDomesticEICPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFDomesticEICPage2 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFDomesticEICPage3 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFDomesticEICPage4 alloc] initWithCertificate:self.certificate]];
    [self addDistributionBoardsToPagesArray:pagesArray];
    [pagesArray addObject:[[ICPDFDomesticEICPageFinal alloc] initWithCertificate:self.certificate]];

} else if ([self.certificate.certificateType.title isEqualToString:@"EICR"]) {
    [pagesArray addObject:[[ICPDFEICRPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRPage2 alloc] initWithCertificate:self.certificate]];
    [self addObservationsToPagesArray:pagesArray];
    [self addDistributionBoardsToPagesArray:pagesArray];
    [pagesArray addObject:[[ICPDFEICRInspection alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRInspectionPage1 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRInspectionPage2 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRInspectionPage3 alloc] initWithCertificate:self.certificate]];
    [pagesArray addObject:[[ICPDFEICRPageFinal alloc] initWithCertificate:self.certificate]];
}

// Set page count on all pages
int pageNumber = 0;
for (ICCertificateComponent *page in pagesArray) {
    page.pageNumber.text = [NSString stringWithFormat:@"%d", ++pageNumber];
    page.pageCount.text = [NSString stringWithFormat:@"%d", pagesArray.count];
}

NSData *pdfData = [self createPdfWithPages:pagesArray];
[self performSelectorOnMainThread:@selector(pdfDone:) withObject:pdfData waitUntilDone:YES];

}

- (void)pdfDone:(NSData *)data
{
self.pdfData = data;
[self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8" baseURL:nil];
[ICUtils removeProgressView];
}

- (NSData *)createPdfWithPages:(NSArray *)pages
{
// Creates a mutable data object for updating with binary data, like a byte array
NSMutableData *pdfData = [NSMutableData data];

ICCertificateComponent *firstPage = [pages objectAtIndex:0];

    UIGraphicsBeginPDFContextToData(pdfData, firstPage.contentView.bounds, nil);

for (int i = 0; i < pages.count; i++) {
    ICCertificateComponent *thisPage = [pages objectAtIndex:i];
    UIGraphicsBeginPDFPageWithInfo(thisPage.contentView.bounds, nil);
    //
   // CGContextSetInterpolationQuality((__bridge CGContextRef)(thisPage), kCGInterpolationHigh); CGContextSetRenderingIntent((__bridge CGContextRef)(thisPage), kCGRenderingIntentDefault);
   //

    CGContextRef pdfContext = UIGraphicsGetCurrentContext();
    [thisPage.contentView.layer renderInContext:pdfContext];
}

UIGraphicsEndPDFContext();

return pdfData;
}

- (void)addDistributionBoardsToPagesArray:(NSMutableArray *)pagesArray
{
int pageCount = pagesArray.count;
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
NSArray *boards = [self.certificate.distributionBoards sortedArrayUsingDescriptors:sortDescriptors];
for (DistributionBoard *thisBoard in boards) {
    DebugLog(@"Creating a board page");
    ICPDFDistributionBoard *boardPage = [[ICPDFDistributionBoard alloc] initWithDistributionBoard:thisBoard];
    boardPage.pageNumber.text = [NSString stringWithFormat:@"%d", ++pageCount];
    DebugLog(@"Page number is %d", pageCount);
    [pagesArray addObject:boardPage];

    NSSortDescriptor *circuitDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
    NSArray *circuitDescriptors = [[NSArray alloc] initWithObjects:circuitDescriptor, nil]; 
    NSArray *circuits = [thisBoard.circuits sortedArrayUsingDescriptors:circuitDescriptors];

    //int circuitCount = circuits.count;
    ICPDFCircuitDetails *circuitDetails = boardPage.circuitDetails;

    int circuitCount = 0;
    for (Circuit *thisCircuit in circuits) {
        circuitCount++;
        if (circuitCount > 16) {
            // Add an extension page
            DebugLog(@"Adding an extension sheet");
            circuitCount = 1;
            ICPDFDistributionBoardExtension *boardExtension = [[ICPDFDistributionBoardExtension alloc] initWithDistributionBoard:thisBoard];
            [pagesArray addObject:boardExtension];
            boardExtension.pageNumber.text = [NSString stringWithFormat:@"%d", ++pageCount];
            circuitDetails = boardExtension.circuitDetails;
        }
        NSString *key = [NSString stringWithFormat:@"circuitRow%d", circuitCount];
        ICCircuitRow *circuitRow = [circuitDetails valueForKey:key];
        [circuitRow populateFromCircuit:thisCircuit];
       }
    }
 }

- (void)addObservationsToPagesArray:(NSMutableArray *)pagesArray
{
int pageCount = pagesArray.count;
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
NSArray *observations = [self.certificate.observations sortedArrayUsingDescriptors:sortDescriptors];

ICPDFObservations *observationsPage = [[ICPDFObservations alloc] initWithCertificate:self.certificate];
if (observations.count > 28) {
    observationsPage.additionalObservations.text = @"\u2714";
    observationsPage.additionalNotesAttachedOrToFollowRef.text = @"Attached";
}
observationsPage.pageNumber.text = [NSString stringWithFormat:@"%d", ++pageCount];
DebugLog(@"Page number is %d", pageCount);
[pagesArray addObject:observationsPage];

ICObservationTable *observationTable = observationsPage.observationTable;

int observationCount = 0;
for (Observation *observation in observations) {
    observationCount++;
    if (observationCount > 28) {
        // Add an extension page
        DebugLog(@"Adding an extension sheet");
        observationCount = 1;
        ICPDFObservationsExtension *observationsExtension = [[ICPDFObservationsExtension alloc] initWithCertificate:self.certificate];
        [pagesArray addObject:observationsExtension];
        observationTable = observationsExtension.observationTable;
    }
    NSString *key = [NSString stringWithFormat:@"observationRow%d", observationCount];
    ICObservationRow *observationRow = [observationTable valueForKey:key];
    [observationRow populateFromObservation:observation];
  }

 }
4

1 に答える 1

0

機器を使用して、保持されているがリークされていないメモリによるリークとメモリ損失をチェックします。後者は、まだポイントされている未使用のメモリです。InstrumentsのAllocationsInstrumentでHeapshotを使用します。

Heapshotを使用してメモリの重複を見つける方法については、bbumブログを参照してください。

基本的に、Instruments割り当てツールを実行し、ヒープショットを取得し、コードの直感を実行し、別のヒープショットを3〜4回繰り返す方法があります。これは、反復中に割り当てられ、解放されなかったメモリを示します。

結果を把握するために、個々の割り当てを確認するために開示します。

オブジェクト使用インスツルメントの保持、リリース、および自動リリースが発生する場所を確認する必要がある場合は、次のようにします。

機器で実行し、[割り当て]で[参照カウントの記録]をオンに設定します(オプションを設定するには、記録を停止する必要があります)。ピッカーを実行し、記録を停止し、そこにあるivar(datePickerView)を検索し、ドリルダウンすると、すべての保持、リリース、および自動リリースが発生した場所を確認できます。

于 2013-01-15T00:24:31.433 に答える