[英]NSString memory leak
我在從NSManagedObject構建電子郵件字符串的方法中遇到內存泄漏。 該字符串是使用NSString便捷方法創建的,因此應自動釋放。 我想念什么? 下面的代碼...儀器正在標記buildString在該方法底部附近的最終出現(請參見代碼中的注釋):
-(void)buildEmailMessage {
//check for presence of lat and lon data
BOOL hasStartLatLon = NO;
BOOL hasEndLanLon = NO;
NSString *startLat;
NSString *startLong;
NSString *endLat;
NSString *endLong;
NSString *mapURL;
NSString *finalMapURL;
if( [managedObject valueForKey:@"startLat"] > 0 ){
hasStartLatLon = YES;
startLat = [self formatLatLon:[managedObject valueForKey:@"startLat"]];
startLong= [self formatLatLon:[managedObject valueForKey:@"startLong"]];
}
if( [managedObject valueForKey:@"endLat"] > 0 ) {
hasEndLanLon = YES;
endLat = [self formatLatLon:[managedObject valueForKey:@"endLat"]];
endLong= [self formatLatLon:[managedObject valueForKey:@"endLong"]];
}
// Build strings from managedObject
// Start with the trip info already validated
NSString *tripName = [managedObject valueForKey:@"tripName"];
NSString *intro = [NSString stringWithString:@"Please contact the approriate authorities and provide them with the enclosed information if our party does not return withing 12 hours of the return date shown below. Thanks.
"]; id vStartDate = [managedObject valueForKey:@"startDate"]; NSString *startDate = [NSString stringWithFormat:@"
Start Date: %@", [vStartDate managedObjectValueDisplay]]; id vEndDate = [managedObject valueForKey:@"endDate"]; NSString *endDate = [NSString stringWithFormat:@"
End Date: %@
", [vEndDate managedObjectValueDisplay]];
NSString *startFrom = [NSString stringWithFormat:@"Departing from:
%@", [managedObject valueForKey:@"startFrom"]]; if( hasStartLatLon ){ startFrom = [startFrom stringByAppendingString:@"
"]; startFrom = [startFrom stringByAppendingString:[self getLatLon:@"start"]]; } startFrom = [startFrom stringByAppendingString:@"
"];
NSString *endAt = [NSString stringWithFormat:@"Returning to:
%@", [managedObject valueForKey:@"endAt"]]; if( hasStartLatLon ){ endAt = [endAt stringByAppendingString:@"
"]; endAt = [endAt stringByAppendingString:[self getLatLon:@"end"]]; } endAt = [startFrom stringByAppendingString:@"
"];
// Add a link to Google Maps if there is geodata
if (hasStartLatLon || hasEndLanLon) {
if (hasStartLatLon) {
mapURL = [NSString stringWithFormat:@"http://maps.google.com/?q=%@,%@+(%@)&ll=%@,%@&z=14&t=p", startLat, startLong, [managedObject valueForKey:@"startFrom"], startLat, startLong];
} else {
mapURL = [NSString stringWithFormat:@"http://maps.google.com/?q=%@,%@+(%@)&ll=%@,%@&z=14&t=p", endLat, endLong, [managedObject valueForKey:@"endAt"], endLat, endLong];
}
NSString* escapedUrlString =[mapURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"escaped map url = %@", escapedUrlString);
finalMapURL = [NSString stringWithFormat:@"Link to Google Map:
%@", escapedUrlString];
}
NSString *routeInfo = [NSString stringWithFormat:@"Route Information:
%@
", [managedObject valueForKey:@"routeInfo"]];
// Check for vehicle info
BOOL hasVehicleMakeAndModel = NO;
BOOL hasVehicleLicenseNumber = NO;
BOOL hasVehicleState = NO;
NSString *vehicleMakeAndModel = [managedObject valueForKey:@"vehicleMakeAndModel"];
NSString *vehicleLicenseNumber = [managedObject valueForKey:@"vehicleLicenseNumber"];
NSString *vehicleState = [managedObject valueForKey:@"vehicleState"];
if ( vehicleMakeAndModel.length > 0 ) {
hasVehicleMakeAndModel = YES;
}
if ( vehicleLicenseNumber.length > 0 ) {
hasVehicleLicenseNumber = YES;
}
if ( vehicleState.length > 0 ) {
hasVehicleState = YES;
}
//Build the vehicle string
NSString *vehicleString;
if (hasVehicleMakeAndModel || hasVehicleLicenseNumber || hasVehicleState) {
vehicleString = [NSString stringWithString:@"Vehicle Information:
"]; } if (hasVehicleMakeAndModel) { vehicleString = [vehicleString stringByAppendingString:@"Make/Model: "]; vehicleString = [vehicleString stringByAppendingString:vehicleMakeAndModel]; vehicleString = [vehicleString stringByAppendingString:@"
"]; } if (hasVehicleLicenseNumber) { vehicleString = [vehicleString stringByAppendingString:@"License #: "]; vehicleString = [vehicleString stringByAppendingString:vehicleLicenseNumber]; vehicleString = [vehicleString stringByAppendingString:@"
"]; } if (hasVehicleState) { vehicleString = [vehicleString stringByAppendingString:@"State: "]; vehicleString = [vehicleString stringByAppendingString:vehicleState]; } // Get the NSSet of party members from the managedObject // and build the party members/emergency contact info NSSet *membersSet = [managedObject valueForKey:@"members"]; NSString *membersString; if ( [membersSet count] > 0) { membersString = @"
Party Members:
";
NSArray *membersArray = [NSArray arrayByOrderingSet:membersSet byKey:@"lastName" ascending:YES];
for (NSManagedObject *oneObject in membersArray) {
BOOL hasFirstName = NO;
BOOL hasLastName = NO;
BOOL hasAge = NO;
BOOL hasContactName = NO;
BOOL hasContactNumber = NO;
NSString *memberFirstName = [oneObject valueForKey:@"firstName"];
NSString *memberLastName = [oneObject valueForKey:@"lastName"];
NSNumber *memberAgeNum = [oneObject valueForKey:@"age"];
NSString *memberAgeString;
if (memberAgeNum > 0) {
memberAgeString = [NSString stringWithFormat:@"%d", [memberAgeNum intValue]];
} else {
memberAgeString = [NSString stringWithString:@""];
}
NSString *contactName = [oneObject valueForKey:@"contactName"];
NSString *contactNumber = [oneObject valueForKey:@"contactNumber"];
if ( [memberFirstName length] > 0) {
hasFirstName = YES;
}
if ( [memberLastName length] > 0) {
hasLastName = YES;
}
if ( [memberAgeString length] > 0) {
hasAge = YES;
}
if ( [contactName length] > 0) {
hasContactName = YES;
}
if ( [contactNumber length] > 0) {
hasContactNumber = YES;
}
NSString *oneMemberString = [NSString stringWithString:@""]; if (hasFirstName) { oneMemberString = [oneMemberString stringByAppendingFormat:@"%@ ", memberFirstName]; } if (hasLastName) { oneMemberString = [oneMemberString stringByAppendingString:memberLastName]; } if (hasAge) { oneMemberString = [oneMemberString stringByAppendingFormat:@", %@", memberAgeString]; } if (hasContactName) { oneMemberString = [oneMemberString stringByAppendingFormat:@"
Emergency Contact:
%@", contactName]; } if (hasContactNumber) { oneMemberString = [oneMemberString stringByAppendingFormat:@"
Phone: %@
", contactNumber];
}
membersString = [membersString stringByAppendingString:oneMemberString];
}
}
NSString *buildString = [NSString stringWithFormat:@"Trip Plan for:
%@
", tripName];
buildString = [buildString stringByAppendingString: intro];
buildString = [buildString stringByAppendingString: startDate];
buildString = [buildString stringByAppendingString: endDate];
buildString = [buildString stringByAppendingString: startFrom];
buildString = [buildString stringByAppendingString: endAt];
if (hasStartLatLon || hasEndLanLon) buildString = [buildString stringByAppendingString: finalMapURL];
buildString = [buildString stringByAppendingString: routeInfo];
// Append the vehicle string if any vehicle data is present
if (hasVehicleMakeAndModel || hasVehicleLicenseNumber || hasVehicleState) {
buildString = [buildString stringByAppendingString: vehicleString];
}
// Append the members string if any members data is present
// **MEMORY LEAK** flagged on the line enclosed by the if statement below
if ( [membersSet count] > 0) {
buildString = [buildString stringByAppendingString: membersString];
}
self.myEmailString = [NSString stringWithString:buildString];
}
-(NSString *)formatLatLon:(NSNumber *)value {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setPositiveFormat:@"##0.00000"];
NSString *returnString = [formatter stringFromNumber:value];
[formatter release];
return returnString;
}
您如何myEmailString
@property
定義的? 用copy
還是retain
? (您應該將copy
與NSString
對象一起使用。)如果是這樣,並且您沒有在dealloc
執行[myEmailString release]
,則可能是泄漏。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.