![](/img/trans.png)
[英]Problem with custom UINavigationBar for MFMailComposeViewController
[英]MFMailComposeViewController problem
這個問題可能不特定於MFMailComposeViewController,但這就是我遇到的問題...
我正在為MFMailComposeViewController的messageBody構建NSString“ myEmailString”,並將其存儲在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];
}
您的ivar如何聲明? 被宣布為財產嗎? 無論如何,它不會自動為您保留。
你要么要做
myEmailString = [[NSString stringWithString:buildString] retain];
要么
self.myEmailString = [NSString stringWithString:buildString];
如果您將myEmailString聲明為
@property (nonatomic, retain) NSString *myEmailString
想想看:如果所有的ivars被自動保留適合你,那你會怎么有,你沒有想保留一個變量? 這就是為什么它不能那樣工作的原因。
在buildEmailMessage中創建myEmail字符串時,您永遠不會保留該字符串。 因此,在離開該功能后,它將自動釋放。 那么在調用dealloc時您的保留計數將為0,這將導致崩潰。 如果要保留變量,則需要如下所示
myEmailString = [[NSString stringWithString:buildString] retain];
那么您可以安全地致電[myEmailString release]
stringWithString:
創建一個新字符串並在將其返回給您之前自動釋放它。 除非保留返回的字符串,否則無需在dealloc方法中釋放它。
在將字符串存儲到iVar中之前,您應該保留它:
myEmailString = [[NSString stringWithString:buildString] retain];
沒有它,它將變得無效,因為它會在程序執行期間稍后自動釋放。 這也將確保在調用析構函數時仍分配該文件,從而防止版本崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.