3

アプリで奇妙な問題に直面しており、あなたの助けが必要です!
MFMailComposeViewController を使用して、添付データ付きの電子メールを送信しています。添付ファイルは、PDF、CSV、または XLS ファイルのいずれかです。ZIP ファイルをメールに追加することもできます。

ほとんどの場合、すべて正常に動作しますが、添付ファイルが XLS であり、ZIP が追加されている場合に (実際には非常に頻繁に)、複数のメモリ警告が表示され、コンポーザは MFMailComposeResultFailed を返し、まったく役に立たないエラーが返されます (コード エラー 1、「操作を完了できませんでした。(MFMailComposeErrorDomain エラー 1.)」)。

私の質問は、なぜそれを行うのですか? メモリの警告は、何かが適切に管理されていないことを示していると思いますが、何が原因かわかりません...

ここにメールを送信するための私のコードがあります

-(void) sendMail {

    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; 
    [self prepareMailPicker:picker];

    NSString *filePath = [self getFilePath:pType];

    NSString *zipFile = [self getZipPath];

    NSString *mimeType;
    int userPhoto = [User getCSVPhoto];

    switch (pType) {
        case EPDF:
            mimeType = @"application/pdf";
            userPhoto = [User getPDFPhoto];
            break;
        case ECSV:
            mimeType = @"text/csv";
            break;
        case EExcel:
            mimeType = @"application/vnd.ms-excel";
            break;

        default:
            break;
    }

    NSData *attachmentData = [NSData dataWithContentsOfFile:filePath];
    [picker addAttachmentData:attachmentData mimeType:mimeType fileName:[filePath lastPathComponent]];

    if (userPhoto == 1 && shouldAddZip) {
        NSData *zipData = [NSData dataWithContentsOfFile:zipFile];
        [picker addAttachmentData:zipData mimeType:@"application/zip" fileName:[zipFile lastPathComponent]];
    }

    shouldAddZip = NO;

    [self presentModalViewController:picker animated:YES];
}

-(void) prepareMailPicker:(MFMailComposeViewController*)picker {

    picker.mailComposeDelegate = (id<MFMailComposeViewControllerDelegate>)self;

    picker.navigationBar.tintColor = grayDark;

    [picker setSubject:[TextManager textForKey:@"EMAIL_SUBJECT"]];

    NSString *email = [[User currentUser] getEmail];

    if (email && ![email isEqualToString:@""])
        [picker setToRecipients:[NSArray arrayWithObject:email]];

    NSString *emailBody = [TextManager textForKey:@"EMAIL_TEXT"];
    [picker setMessageBody:emailBody isHTML:YES];
}

どんな助けでも大歓迎です!

編集: @matt が尋ねたように、何も nil に設定されていないことを証明するログを次に示します。

filePath : /var/mobile/Applications/A57F5CD2-E3FE-4417-8810-D746A22CF434/Documents/iNdF_Export_2012-11-19.xls
zipFile : /var/mobile/Applications/A57F5CD2-E3FE-4417-8810-D746A22CF434/Documents/iNdF_recus_2012-11-19.zip
attachmentData : (NSConcreteData *) <0x1d9c3c20> 53 874 bytes
zipData : (NSConcreteData *) <0x1f989100> 6 838 456 bytes
4

3 に答える 3

1

あなたが言うように、あなたが受けているメモリ警告を考えると、問題はおそらくメモリ管理に関係しているようです。

コードは、2番目のファイルのzipDataを取得するために送信されても​​、最初のファイルからattachmentDataへの参照カウントを保持しています。内部的には、ピッカーはおそらくそのデータをコピーしています…</ p>

したがって、大きなデータへの参照をできるだけ早く解放するためにできることが多ければ多いほど、メモリ警告が表示されない可能性が高くなります。

また、メモリ不足のためにピッカーがアタッチメントを完了できず、早期リリースを実行することでそれを乗り越えることができるという問題がある場合は、次の方法でコードを分割すると役立つ場合があります。

- (void)sendMailPicker:(MFMailComposeViewController*)picker addAttachmentUsingMimeType:(NSString*)mimeType {
    NSString *filePath = [self getFilePath:pType];
    NSData *attachmentData = [NSData dataWithContentsOfFile:filePath];
    [picker addAttachmentData:attachmentData mimeType:mimeType fileName:[filePath lastPathComponent]];
}

- (void)sendMailAddPhotoUsingPicker:(MFMailComposeViewController*)picker {
    NSString *zipFile = [self getZipPath];
    NSData *zipData = [NSData dataWithContentsOfFile:zipFile];
    [picker addAttachmentData:zipData mimeType:@"application/zip" fileName:[zipFile lastPathComponent]];
}

- (void)sendMail {

    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; 
    [self prepareMailPicker:picker];

    NSString *mimeType;
    int userPhoto = [User getCSVPhoto];

    switch (pType) {
        case EPDF:
            mimeType = @"application/pdf";
            userPhoto = [User getPDFPhoto];
            break;
        case ECSV:
            mimeType = @"text/csv";
            break;
        case EExcel:
            mimeType = @"application/vnd.ms-excel";
            break;

        default:
            break;
    }

    [self sendMailPicker:picker addAttachmentUsingMimeType:mimeType];
    if (userPhoto == 1 && shouldAddZip) {
        [self sendMailAddPhotoUsingPicker:picker];
    }

    shouldAddZip = NO;

    [self presentModalViewController:picker animated:YES];
}
于 2012-11-21T06:38:12.277 に答える
0

ヒープに作成した NSData を作成するとき、問題はメモリに関連していると思います。大きすぎると、メモリの警告が表示されるようになります。メモリを回避する 1 つの方法は、メモリ マップされた NSData または NSStream を作成することですが、NSStream をメール コンポーザに統合する方法がわかりません。あなたの添付ファイルの平均サイズはどれくらいですか?
また、割り当てを使用してアプリのプロファイリングを試みて、アプリのメモリ フットプリントを確認することもできます。おそらく、すでに高すぎます。

于 2012-11-21T06:47:32.170 に答える
0

私が以前に直面したいくつかの問題のように。1. 「到達可能性」クラス ファイルを使用して、インターネットが利用可能であることを確認してください。2. データサイズが制限内であることを確認してください。3. デバイスでメール ID を設定したことを確認してください。[yourobj cansendmail] 関数を呼び出して、メールを送信できるかどうかを確認することもできます。

于 2012-11-27T07:23:01.830 に答える