0

我在下面的项目中有一个真实的例子。我的目标是挑选出最有可能接收短信的电话号码,并且只有那个(电话)号码。当我最后不释放内存时,一切都很好,但是我们不能拥有它,可以吗?我的问题是:在下面的示例中,释放内存的正确方法是在哪里(以及如何)?

// Called after a person has been selected by the user. Return YES if you want the person to be displayed.
// Return NO to do nothing (the delegate is responsible for dismissing the peoplepicker)
- (BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker 
    shouldContinueAfterSelectingPerson: (ABRecordRef)person
{     
 // Retrieving the person's most likely phonenumber (kABPersonPhoneProperty)
 CFStringRef phoneNumber, phoneNumberLabel;

 ABMutableMultiValueRef multiValueReference = ABMultiValueCreateMutable(kABMultiStringPropertyType); 
 multiValueReference = ABRecordCopyValue(person, kABPersonPhoneProperty);

 NSMutableString *mostLikelyPhoneNumber = [[NSMutableString alloc] init];

 // Iterating through all the phone numbers in the list
 for (CFIndex i = 0; i < ABMultiValueGetCount(multiValueReference); i++) {

  phoneNumberLabel = ABMultiValueCopyLabelAtIndex(multiValueReference, i);
  phoneNumber      = ABMultiValueCopyValueAtIndex(multiValueReference, i);

  // Converting to NSString for easier comparison (this way I have only NSStrings)
  NSString *NSStringphoneNumberLabel =  [[NSString alloc] init];
  NSString *NSStringphoneNumber =  [[NSString alloc] init];

  // Copying the contents of the CFStringRef to my NSString pointers
  NSStringphoneNumberLabel = (NSString *) phoneNumberLabel;
  NSStringphoneNumber = (NSString *) phoneNumber;

  LOG (@"Phone number: %@/%@", phoneNumberLabel, phoneNumber); // No problem so far!
  LOG (@"Phone number: %@/%@", NSStringphoneNumberLabel, NSStringphoneNumber); // No problem so far!

  // If this phone number has a "iphone" or a "mobile" label, save it to mostLikelyPhoneNumber
  if ([NSStringphoneNumberLabel isEqualToString:@"_$!<Mobile>!$_"]) 
  {
   mostLikelyPhoneNumber = (NSMutableString *) NSStringphoneNumber;
  }

  else if ([NSStringphoneNumberLabel isEqualToString:@"iPhone"])
  {
   mostLikelyPhoneNumber = (NSMutableString *) NSStringphoneNumber;
   // However, if it was an "iphone", break out of the loop. (Can't get any better than iPhone)
   break; 
  }

  _tfGSM.text = (NSString*) mostLikelyPhoneNumber;

  // Releasing memory used in this particular iteration
  [NSStringphoneNumber release];
  [NSStringphoneNumberLabel release];  
 }

 // Releasing rest of memory  THIS IS WHERE IT CRASHES!
 [mostLikelyPhoneNumber release];
 CFRelease(phoneNumberLabel); 
 CFRelease(phoneNumber); 
 CFRelease(multiValueReference);

 [self dismissModalViewControllerAnimated:YES];
 return NO; // As soon as a person is picked, we end this address book sidetrip and return to the app
}
4

1 回答 1

1

您的基本问题似乎是不理解是什么=意思。

当您将一个指针值分配给另一个时,就像在这个随机选择的示例中一样:

mostLikelyPhoneNumber = (NSMutableString*) NSStringphoneNumber;

没有将第二个字符串的内容复制到可变的第一个字符串中。相反,您正在覆盖指针本身。NSMutableString因此,指向您之前分配的原始指针丢失了,您现在只有对该NSStringphoneNumber值的第二次引用,而您并不拥有该值。

您在代码中的任何地方都做几乎相同的事情。

当您最终希望清理时,您不能,因为您不再拥有指向任何已分配对象的指针;当你尝试时,你反而过度释放了一堆你不拥有的东西,导致崩溃。

通常在这些情况下,我建议去阅读内存管理指南,但坦率地说,我认为你最好回到基础,先做一些补救的 C。

于 2010-07-30T09:05:05.663 回答