IOS Modify Address Book contact addresses crash cause analysis

Source: Internet
Author: User
Tags vars

In the current project, the iOS system address book needs to be read, modified operation. At the time of the address modification, there was a strange phenomenon:

If the contact does not have an address field (or a brand new contact), it is possible to modify its address to be successful.

If the person has an address field, the modification will crash when it is done. Console typing:

-[cfstring release]: message sent to deallocated instance 0x81d26f0

This should be a zombie object that repeats the release of an object. First I check the code to modify the Address book, but I do not see the problem, the following is the code

[OBJC]View Plaincopy
  1. Set address
  2. Abmutablemultivalueref multiaddress = abmultivaluecreatemutable (Kabmultidictionarypropertytype);
  3. For (phonetypepair* p in contact. Addressarr) {
  4. //Content judgment null
  5. if ([P. Content length]==0) {
  6. continue;
  7. }
  8. nsmutabledictionary *addressdictionary = [[Nsmutabledictionary alloc] init];
  9. //address is written to the street field only
  10. [Addressdictionary setobject:[p. Content Mutablecopy] forkey: (NSString *)  Kabpersonaddressstreetkey];
  11. [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddresscitykey];
  12. [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddressstatekey];
  13. [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddresszipkey];
  14. [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddresscountrycodekey];
  15. //Put the dictionary into a multi-valued object
  16. if ([P. Type isequaltostring:kaddresstype_work]) {
  17. Abmultivalueaddvalueandlabel (Multiaddress, Cfbridgingretain (addressdictionary), Kabworklabel, NULL);
  18. }Else if ([P. Type Isequaltostring:kaddresstype_home]) {
  19. Abmultivalueaddvalueandlabel (Multiaddress, Cfbridgingretain (addressdictionary), Kabhomelabel, NULL);
  20. }else{
  21. Abmultivalueaddvalueandlabel (Multiaddress, Cfbridgingretain (addressdictionary), Kabotherlabel, NULL);
  22. }
  23. }
  24. Abrecordsetvalue (person, Kabpersonaddressproperty, multiaddress, NULL);
  25. Abaddressbookaddrecord (addressbook, person, nil);
  26. Abaddressbooksave (AddressBook, NULL);
  27. if (multiaddress) {
  28. Cfrelease (multiaddress);
  29. }

Program crashes in Abaddressbooksave (AddressBook, NULL); Best of all, Google looked at a lot of information to see if the "multi-value" of the object used wrong, or code order problem. Have no results.

Later, I remember instruments this tool to view zombie objects. Immediately starting profile. The results are as follows:

The place of Zombie is Abcmultivaluedestroy. However, I have noticed Addressbookengine's getaddress: function. Suddenly I realized that the problem should be read when the CF and OC objects were converted. Randomly, I opened the URL and turned to arc description

__bridge only does type conversion, but does not modify the object (memory) management rights;
__bridge_retained (You can also use Cfbridgingretain) to convert objects from Objective-c to core foundation objects while handing over the management of the object (memory) to us, Subsequent use of cfrelease or related methods to release objects;
__bridge_transfer (You can also use cfbridgingrelease) to convert a core foundation object to an Objective-c object while handing over the management of the object (memory) to arc.

Well, the problem should be reading the address: Look at the code.

[OBJC]View Plaincopy
  1. /**
  2. * Get Address
  3. *
  4. * @param recordref contacts Single Contact reference
  5. *
  6. * @return Address
  7. */
  8. -(nsdictionary*) getaddress: (abrecordref) recordref{
  9. //1. Judgment
  10. if (recordref = = nil) {
  11. return Nil;
  12. }
  13. Nsmutablearray *addresshome = [[Nsmutablearray alloc]init];
  14. Nsmutablearray *addresswork = [[Nsmutablearray alloc]init];
  15. Nsmutablearray *other = [[Nsmutablearray alloc]init];
  16. //2. Creating a dictionary to get a list of multi-key values
  17. nsmutabledictionary *multivaluedic = [[Nsmutabledictionary alloc] initwithcapacity:1];
  18. Abmultivalueref Multivaluearr = Abrecordcopyvalue (RecordRef, Kabpersonaddressproperty);
  19. //3. Encapsulates multiple values into a dictionary.
  20. int count = Multivaluearr?  Abmultivaluegetcount (Multivaluearr): 0;
  21. if (Count > 0) {
  22. Count = (count <= kmaxaddressnumber?count:kmaxaddressnumber);
  23. For (int i = 0; i < count; i++) {
  24. @autoreleasepool {
  25. //lable
  26. //Pay attention to bridging, convert CF object to OC object. Under Arc, the OC object is automatically released: Reference http://blog.csdn.net/hherima/article/details/16356577
  27. nsstring* label = Cfbridgingrelease (Abmultivaluecopylabelatindex (multivaluearr,i));
  28. //value
  29. Cfdictionaryref dict = Abmultivaluecopyvalueatindex (Multivaluearr, i);
  30. nsstring* Street =cfbridgingrelease (Cfdictionarygetvalue (Dict, Kabpersonaddressstreetkey));
  31. nsstring* City =cfbridgingrelease (Cfdictionarygetvalue (Dict, Kabpersonaddresscitykey));
  32. nsstring* Country =cfbridgingrelease (Cfdictionarygetvalue (Dict, Kabpersonaddresscountrykey));
  33. //cfrelease (dict);//should be deleted
  34. nsstring *syntheticaddress = [NSString stringwithformat:@ "%@%@%@"
  35. , (Street?street:@ "")
  36. , (city?city:@ "")
  37. , (country?country:@ "")];
  38. if (label = = Nil | | [Label isequaltostring:@ "_$!
  39. [Addresshome addobject:syntheticaddress];
  40. }
  41. Else if ([Label isequaltostring:@ "_$!<work>!$_"]) {
  42. [Addresswork addobject:syntheticaddress];
  43. }
  44. else{
  45. [Other addobject:syntheticaddress];
  46. }
  47. }
  48. }
  49. [Multivaluedic setobject:addresshome forkey:@ (eadressbooktype_addresshome)];
  50. [Multivaluedic setobject:addresswork forkey:@ (eadressbooktype_addresswork)];
  51. [Multivaluedic setobject:other forkey:@ (eadressbooktype_addressother)];
  52. }
  53. //4. Releasing a CF object
  54. if (NULL! = Multivaluearr) {
  55. Cfrelease (Multivaluearr);
  56. Multivaluearr = NULL;
  57. }
  58. return multivaluedic;
  59. }

I made a hypothesis before I could find a specific question. If you return from the beginning of this function, if you do not crash, the explanation is the problem of subsequent code. Sure enough

The problem is:

Cfrelease (DICT);

Since I have used the cfbridgingrelease, it is not necessary to releasedict this object. The main is the above code, is copy from the Internet. No change.

http://blog.csdn.net/hherima/article/details/41594273

IOS Modify Address Book contact addresses crash cause analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.