2013-06-12 5 views
1

나는 내 사용자 지정 클래스 (viewController가 아님)에서 MFMailComposeViewController을 표시합니다. iOS5에서는 잘 작동하지만 iOS6에서는 작성 시트를 발표 한 직후 충돌이 발생합니다. 문제가 발견되었습니다. dealloc 메소드가 뷰를 제시 한 후 호출되므로, 자체는을 할당 해제합니다. 이 메일 컴 포머로 인해 자체에 대한 대리자 메서드를 호출 할 수 없으므로 충돌이 발생합니다. 나는 그것을위한 해결책을 얻지 않았다. 사용중인 고객 : 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

'MFMailComposeViewController'가 제대로 해제 될 때까지 다른 클래스가 '자체'(또는 사용자 정의 클래스)를 유지하는지 확인하십시오. 누가 당신의 '자기'(또는 커스텀 클래스)를 소유하고 있습니까? – holex

+0

@Anil 어쩌면 해결책을 찾았습니까? 같은 문제가 여기에 ... –

+1

@ElisabettaFalivene Delegate 객체가 누군가를 할당 해제하는 것을 방지하기 위해 Inorder는 그것을 강력하게 보유해야합니다. 대리자 객체를 항상 보유 할 수있는 컨트롤러에 속성을 만들었습니다. 'A'가 컨트롤러'B'라고 가정하면 'Mail composer'를 제시하고 위임하는보기입니다. 컨트롤러'A'에서'B'의 참조를 유지했습니다. –

답변

1

는 나에있어서, 상기 presentModalViewController 방법은 아이폰 OS 6.0에서 사용되지 않습니다.

대신 당신은 그렇지

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

당신이 충돌 로그를 표시 할 수 있습니다 사용할 필요가 ??

+0

나는 같은 문제 ... 충돌 로그 메소드가 할당 해제 된 인스턴스 –

+1

에 전송 됨 충돌 로그에 구현되지 않은 메소드가 호출되었다고 기록되어있다. 그 메소드 변경으로 인해 iOS에 메일 컨트롤러를 표시 할 수 있었다. 6.1 성공적으로 완료 처리기가 제대로 호출되지 않았습니까. 적절한지 확인하십시오. –

+0

iam이 어떤 메소드도 호출하지 않고, time delegate (self)가 할당 해제 된 delegate 메소드를 호출하는 mailcomposeViewController. __ [RSEmailService respondsToSelector :] : 할당 된 인스턴스에 메시지가 전송되었습니다. 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' 객체에 관한 것이 아니라'MFMailComposeViewController' 객체의 델리게이트 인'self'에 관한 것입니다. 반면에 'mailer'는 범위가 없어 질 때까지 해제되지 않으므로 충분히 안전합니다. – holex

+0

@ 홀 렉스 : 프로젝트가 ARC를 사용하지 않으면 메일러가 해제되지 않습니다. 그러나 ARC 설정에서 함수 범위 내에서 생성 된 변수는 함수 블록이 완료된 직후 자동으로 해제됩니다 (참조가 유지되지 않는 한). – JapCon

+0

은'ARC'에서 범위가 끝난 후에 아무 것도 살아 있지 않으면 해제 될 것입니다. _local_ mailer 컨트롤러를 스코프 내부의 다른 컨트롤러에 추가하면 더 이상 그 컨트롤러를 사용할 수 없게됩니다. 그러므로 공공 재산을 통해서조차도 살아있을 필요가 없습니다. 나는 그것의'delegate'가 너무 빨리 풀어 놓는다는 것에 대해 말하고있다. 따라서 메일러는 어떠한 객체도 콜백 할 수 없다. – holex