2013-06-12 2 views
1

Iam, представляющий MFMailComposeViewController из моего пользовательского класса (не viewController). В iOS5 он работает нормально, но в iOS6 он сразу же после сбоя выходит из строя. Я нашел проблему метод dealloc получает вызов после представления представления, поэтому self освобождается. Из-за этого mailcomposer не может вызвать метод делегата на себе, поэтому он сбой. Я не получил решение для этого. Am с использованием ARC. Как предотвратить self от освобождения до вызова метода делегата?Ошибка MFMailComposeViewController в iOS6 ARC

-(void)shareOnViewController:(UIViewController *)viewController completion:(ShareCompletionHandler)completion 
{ 

    if ([MFMailComposeViewController canSendMail]) { 

    MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init]; 
    mailer.mailComposeDelegate = self; 
    mailer.modalPresentationStyle = UIModalPresentationPageSheet; 
    [mailer setSubject:[self.userInfo objectForKey:@"title"]]; 

    NSData *imageData = UIImagePNGRepresentation([self.userInfo objectForKey:@"image"]); 
    if (imageData) { 
     [mailer addAttachmentData:imageData mimeType:@"image/png" fileName:@"AttachedImage"]; 
    } 


    NSURL *emailBody = [self.userInfo objectForKey:@"url"]; 
    if (![emailBody isEqual:@""]) { 
     [mailer setMessageBody:[emailBody absoluteString] isHTML:NO]; 
    } 

    [viewController presentModalViewController:mailer animated:YES]; 

    } else { 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unable to send mail" 
                message:@"Device is not configured to send mail" 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil]; 
    [alert show]; 
    } 

self.completionHandler = completion; 

} 
+0

, пожалуйста, убедитесь, что какой-либо другой класс сохраняет ваш 'self' (или пользовательский класс) до тех пор, пока' MFMailComposeViewController' не будет правильно уволен. кто владеет вашим 'self' (или обычным классом)? – holex

+0

@ Возможно, вы нашли решение? Тот же вопрос здесь ... –

+1

@ElisabettaFalivene Inorder, чтобы предотвратить делегирование объекта делегата, кто-то должен его сильно удерживать. Я создал свойство на контроллере, который, вероятно, будет жить всегда, чтобы удерживать объект-делегат. Чтобы быть ясным, если Assume 'A'is controller' B' - это представление, которое представляет «Композитор почты» и делегирует его. Я держу ссылку 'B' в контроллере' A' –

ответ

1

По мне, метод presentModalViewController осуждается в прошивкой 6.0.

Вместо этого вы должны использовать

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion 

Иначе вы можете показать журнал сбоев ??

+0

Я пробовал и то, и другое. Тот же вопрос ... метод журнала сбоев отправлен на освобожденный экземпляр –

+1

В журнале сбоев говорится, что вы пытаетесь вызвать метод, который не был реализован. С изменением этого метода я смог представить почтовый контроллер в iOS 6.1 успешно. Может быть, ваш обработчик завершения неправильно вызван. Проверьте, что это правильно. –

+0

iam не вызывает какой-либо метод, mailcomposeViewController, вызывающий его метод делегата, который освобождает делегат (self). __ [RSEmailService отвечаетSoSelector:]: сообщение отправлено на освобожденный экземпляр 0x9c91600__ –

0
if ([MFMailComposeViewController canSendMail]) { 
     MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] 
                init]; 

    NSData *imageData = UIImagePNGRepresentation(image); 
    mailComposer.mailComposeDelegate = self; 
    [mailComposer setSubject:subject]; 
    NSArray * recipents = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@",NSLocalizedString(@"client_email", @"")],nil]; 

    [mailComposer setToRecipients:recipents]; 

    [mailComposer addAttachmentData:imageData mimeType:@"image/png" fileName:[NSString stringWithFormat:@"imageProfile-%@-%@",someId,lastname]]; 



    mailComposer.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; 

    [vc presentViewController:mailComposer animated:YES completion:nil]; 
} 
else 
{ 
    UIAlertView *tmp = [[UIAlertView alloc] 
         initWithTitle:@"Email Account Not Found" 
         message:@"You need to setup an Email Account!" 
         delegate:self 
         cancelButtonTitle:nil 
         otherButtonTitles:@"Ok", nil]; 

    [tmp show]; 
} 
+0

помогло ли мое решение для вас? – DrDev

0

Одним из возможных коренных причин является ARC.

MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init]; 

почтовик будет автоматически освобожден, как только тело метода полностью выполнена.

Вы можете создать ссылку, чтобы удерживать объект, чтобы избежать ARC, освобождающего его, прежде чем он будет готов.

@property (nonatomic, strong) MFMailComposeViewController * composer; 
.... 


self.composer = [[MFMailComposeViewController alloc] init]; 
... 
[viewController presentViewController:self.composer animated:YES]; 

[Отредактировано предложение]

К сожалению, я пропустить первую часть вашего вопроса, где вы вызывающий метод из другого пользовательского класса.

Я тоже столкнулся с подобной ситуацией. В конце концов, я преобразовал «Custom Class» в класс Singleton.

#pragma mark Singleton Methods 

+ (id)sharedInstance { 
    static CustomClass *sharedInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedInstance = [[self alloc] init]; 
    }); 
    return sharedInstance; 
} 

Это гарантирует, что класс будет сохранен красиво. Но это будет зависеть от использования и дизайна CustomClass. Просто чтобы поделиться тем, что я сделал.

[[CustomClass sharedInstance] shareOnViewController:vc completion:...]; 
+0

Я думаю, что проблема OP не о объекте 'mailer', а о' self', который является делегатом объекта 'MFMailComposeViewController'. с другой стороны, «почтовая программа» не будет выпущена до тех пор, пока не закончится область действия, так что это достаточно безопасно. – holex

+0

@holex: почтовая программа не будет выпущена, если проект НЕ использует ARC. Однако при настройке ARC переменная, созданная в пределах области функции, будет автоматически отпущена сразу после завершения функционального блока (если только она не сохраняется ссылкой). – JapCon

+0

в 'ARC', он будет выпущен, если ничего не оставит объект в живых после завершения действия. если вы добавите этот контроллер _local_ mailer другому контроллеру внутри области действия, который будет поддерживать его в живых, даже если вы больше не будете об этом разбираться. поэтому вам не нужно держать его в живых, даже не через государственную собственность. Я говорю о том, что его «делегат» выпущен слишком рано, поэтому почтовая программа не может перезвонить любому объекту. – holex

Смежные вопросы