代码之家  ›  专栏  ›  技术社区  ›  Alpinista

mfmailcomposeviewController问题

  •  0
  • Alpinista  · 技术社区  · 15 年前

    这个问题可能不是mfmailcomposeviewController特有的,但这就是我遇到的问题…

    • 我正在构建nsstring “myemailString”用于 mfmailcomposeviewController和 以前把它存储在IVAR中 显示 mfmailcomposeviewController作为 模态视图控制器。

    • 我将字符串传递到mfmailcomposeviewController,然后将其作为模式视图控制器呈现。

    • 当模态视图控制器被解除时,我的ivar无效,
      当我释放dealloc中的emailString ivar时,应用程序崩溃了

    下面的代码,我做错了什么?

    -(void)buildEmailMessage {
    int mySection;
    int myRow;
    NSString *buildString = [NSString stringWithFormat:@"<b><p>Ten Essentials Check List</b><br />%@</p>", [myList valueForKey:@"listName"]];
    
    for (mySection = 0; mySection < [[fetchedResultsController sections] count]; mySection ++) {
        NSString *sectionName = [NSString stringWithFormat:@"<p><b>%@ Group</b></p><ul>", [[[fetchedResultsController sections] objectAtIndex:mySection] name]];
        buildString = [buildString stringByAppendingString:sectionName];
        id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:mySection];
        for (myRow = 0; myRow < [sectionInfo numberOfObjects]; myRow ++) {
    
            // Get the managedObject
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:myRow inSection:mySection];
    
            NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
            //Get the related Item object
            Item *item  = [managedObject valueForKey:@"item"];
            NSString *itemName = [NSString stringWithFormat:@"<li>%@</li>", item.itemName];
            buildString = [buildString stringByAppendingString:itemName];
    
        }
        buildString = [buildString stringByAppendingString:@"</ul>"];
    }
    
    
    myEmailString = [NSString stringWithString:buildString];
    NSLog(@"email string = :\n%@", myEmailString);
    [self showPicker];
    }
    
    
    
    #pragma mark -
    #pragma mark Send Mail
    
    -(void)showPicker {
    // This code can run on devices running iPhone OS 2.0 or later  
    // The MFMailComposeViewController class is only available in iPhone OS 3.0 or later. 
    // So, we must verify the existence of the above class and provide a workaround for devices running 
    // earlier versions of the iPhone OS. 
    // We display an email composition interface if MFMailComposeViewController exists and the device can send emails.
    // We launch the Mail application on the device, otherwise.
    
    NSLog(@"Checking OS for MFMailComposeViewController");
    
    Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
    if (mailClass != nil)
    {
        // We must always check whether the current device is configured for sending emails
        if ([mailClass canSendMail])
        {
            [self displayComposerSheet];
        }
        else
        {
            [self launchMailAppOnDevice];
        }
    }
    else
    {
        [self launchMailAppOnDevice];
    }
    }
    
    
    
    
    // Displays an email composition interface inside the application. Populates all the Mail fields. 
    -(void)displayComposerSheet {
    
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    picker.navigationBar.barStyle = UIBarStyleBlack;
    
    
    [picker setSubject:@"Here is your gear check list!"];
    
    
    // Attach an image to the email
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Checkmark_icon" ofType:@"png"];
    NSData *myData = [NSData dataWithContentsOfFile:path];
    [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"Checkmark_icon"];
    
    // Fill out the email body text
    //***** NOTE: This is where I pass the value from my iVar ***** 
    //      into the MFMailComposeViewController
    // 
    NSString *emailBody = [NSString stringWithString:myEmailString];
    [picker setMessageBody:emailBody isHTML:YES];
    NSLog (@"DIsplaying Composer Sheet");
    
    [self presentModalViewController:picker animated:YES];
    
    [picker release];
    }
    
    
    // Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.
    - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error  { 
    //message.hidden = NO;
    // Notifies users about errors associated with the interface
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog (@"Result: canceled");
            break;
        case MFMailComposeResultSaved:
            NSLog (@"Result: saved");
            break;
        case MFMailComposeResultSent:
            NSLog (@"Result: sent");
            break;
        case MFMailComposeResultFailed:
            NSLog (@"Result: failed");
            break;
        default:
            NSLog (@"Result: not sent");
            break;
    }
    [self dismissModalViewControllerAnimated:YES];
    
    // ***** NOTE: Line below was added to fix the invalid iVar problem *****
    myEmailString = @"";
    }
    
    
    #pragma mark -
    #pragma mark Workaround
    
    // Launches the Mail application on the device.
    -(void)launchMailAppOnDevice {
    NSString *recipients = @"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Here is your gear check list!";
    NSString *body = myEmailString;
    
    NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
    email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
    }
    
    - (void)dealloc {
    [managedObjectContext release];
    [fetchedResultsController release];
    [tableview release];
    [myList release];
    [myEmailString release];
    
    [super dealloc];
    }
    
    4 回复  |  直到 15 年前
        1
  •  3
  •   David Maymudes    15 年前

    你的IVAR是如何申报的?它被宣布为财产吗?无论如何,它不会自动为您保留。

    要么你需要做

    myEmailString = [[NSString stringWithString:buildString] retain];
    

    self.myEmailString = [NSString stringWithString:buildString];
    

    如果将myemailString声明为

    @property (nonatomic, retain) NSString *myEmailString
    

    考虑一下:如果所有的ivar都自动为您保留,那么您将如何拥有一个变量 没有 想保留吗?这就是为什么它不能那样工作的原因。

        2
  •  1
  •   John Stallings    15 年前

    在buildemailmessage中创建myemail字符串时,永远不会保留该字符串。因此,在离开函数之后,它是自动释放的。然后当调用dealoc时,您的保留计数将为0,这将导致崩溃。如果要保留变量,则需要使用以下行

    myEmailString = [[NSString stringWithString:buildString] retain];

    然后你可以打电话 [myEmailString release] 安全地

        3
  •  1
  •   Jasarien    15 年前

    stringWithString: 创建一个新字符串并在返回给您之前自动释放它。除非保留返回的字符串,否则不需要在DealLoc方法中释放它。

        4
  •  1
  •   DeathByCode    15 年前

    在将字符串存储到IVAR中之前,应该保留它:

    myEmailString = [[NSString stringWithString:buildString] retain];
    

    如果没有这个,它将变得无效,因为在程序执行过程中稍后会自动释放它。这还将确保在调用析构函数时仍然分配它,从而防止释放崩溃。