Проблемы с освобождением памяти в Objective-C - PullRequest
0 голосов
/ 30 июля 2010

У меня есть реальный пример из моего проекта ниже. Моя цель - выбрать наиболее вероятный номер телефона для приема SMS и только этот (телефонный) номер. Все работает хорошо, когда я не освобождаю память в конце, но у нас не может быть этого, не так ли? Мой вопрос: где (и как) является правильным способом освобождения памяти в примере ниже?

// 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
}

1 Ответ

1 голос
/ 30 июля 2010

Кажется, ваша основная проблема не в том, что означает =.

Когда вы присваиваете одно значение указателя другому, как в этом случайно выбранном примере:

mostLikelyPhoneNumber = (NSMutableString*) NSStringphoneNumber;

вы не копирование содержимого второй строки в изменяемую первую строку.Скорее вы перезаписываете сам указатель.Таким образом, исходный указатель на NSMutableString, который вы выделили ранее, равен lost , и теперь у вас есть только вторая ссылка на значение NSStringphoneNumber, которому не принадлежит .

Вы делаете почти одно и то же везде в своем коде.

Когда вы в конце концов надеетесь на очистку, вы не сможете этого сделать, потому что у вас больше нет указателей ни на один изваши выделенные объекты;и когда вы пытаетесь , вместо этого вы перепроизводите кучу вещей, которые вам не принадлежат, что приводит к сбою.

Обычно в таких ситуациях я бы предложил пойти и прочитать руководство по управлению памятью , но, честно говоря, я думаю, что вам лучше вернуться к основам и сначала сделать некоторые исправления C.

...