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
- Set address
- Abmutablemultivalueref multiaddress = abmultivaluecreatemutable (Kabmultidictionarypropertytype);
- For (phonetypepair* p in contact. Addressarr) {
- //Content judgment null
- if ([P. Content length]==0) {
- continue;
- }
- nsmutabledictionary *addressdictionary = [[Nsmutabledictionary alloc] init];
- //address is written to the street field only
- [Addressdictionary setobject:[p. Content Mutablecopy] forkey: (NSString *) Kabpersonaddressstreetkey];
- [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddresscitykey];
- [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddressstatekey];
- [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddresszipkey];
- [Addressdictionary SetObject:@ "" forkey: (NSString *) Kabpersonaddresscountrycodekey];
- //Put the dictionary into a multi-valued object
- if ([P. Type isequaltostring:kaddresstype_work]) {
- Abmultivalueaddvalueandlabel (Multiaddress, Cfbridgingretain (addressdictionary), Kabworklabel, NULL);
- }Else if ([P. Type Isequaltostring:kaddresstype_home]) {
- Abmultivalueaddvalueandlabel (Multiaddress, Cfbridgingretain (addressdictionary), Kabhomelabel, NULL);
- }else{
- Abmultivalueaddvalueandlabel (Multiaddress, Cfbridgingretain (addressdictionary), Kabotherlabel, NULL);
- }
- }
- Abrecordsetvalue (person, Kabpersonaddressproperty, multiaddress, NULL);
- Abaddressbookaddrecord (addressbook, person, nil);
- Abaddressbooksave (AddressBook, NULL);
- if (multiaddress) {
- Cfrelease (multiaddress);
- }
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
- /**
- * Get Address
- *
- * @param recordref contacts Single Contact reference
- *
- * @return Address
- */
- -(nsdictionary*) getaddress: (abrecordref) recordref{
- //1. Judgment
- if (recordref = = nil) {
- return Nil;
- }
- Nsmutablearray *addresshome = [[Nsmutablearray alloc]init];
- Nsmutablearray *addresswork = [[Nsmutablearray alloc]init];
- Nsmutablearray *other = [[Nsmutablearray alloc]init];
- //2. Creating a dictionary to get a list of multi-key values
- nsmutabledictionary *multivaluedic = [[Nsmutabledictionary alloc] initwithcapacity:1];
- Abmultivalueref Multivaluearr = Abrecordcopyvalue (RecordRef, Kabpersonaddressproperty);
- //3. Encapsulates multiple values into a dictionary.
- int count = Multivaluearr? Abmultivaluegetcount (Multivaluearr): 0;
- if (Count > 0) {
- Count = (count <= kmaxaddressnumber?count:kmaxaddressnumber);
- For (int i = 0; i < count; i++) {
- @autoreleasepool {
- //lable
- //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
- nsstring* label = Cfbridgingrelease (Abmultivaluecopylabelatindex (multivaluearr,i));
- //value
- Cfdictionaryref dict = Abmultivaluecopyvalueatindex (Multivaluearr, i);
- nsstring* Street =cfbridgingrelease (Cfdictionarygetvalue (Dict, Kabpersonaddressstreetkey));
- nsstring* City =cfbridgingrelease (Cfdictionarygetvalue (Dict, Kabpersonaddresscitykey));
- nsstring* Country =cfbridgingrelease (Cfdictionarygetvalue (Dict, Kabpersonaddresscountrykey));
- //cfrelease (dict);//should be deleted
- nsstring *syntheticaddress = [NSString stringwithformat:@ "%@%@%@"
- , (Street?street:@ "")
- , (city?city:@ "")
- , (country?country:@ "")];
- if (label = = Nil | | [Label isequaltostring:@ "_$!
- [Addresshome addobject:syntheticaddress];
- }
- Else if ([Label isequaltostring:@ "_$!<work>!$_"]) {
- [Addresswork addobject:syntheticaddress];
- }
- else{
- [Other addobject:syntheticaddress];
- }
- }
- }
- [Multivaluedic setobject:addresshome forkey:@ (eadressbooktype_addresshome)];
- [Multivaluedic setobject:addresswork forkey:@ (eadressbooktype_addresswork)];
- [Multivaluedic setobject:other forkey:@ (eadressbooktype_addressother)];
- }
- //4. Releasing a CF object
- if (NULL! = Multivaluearr) {
- Cfrelease (Multivaluearr);
- Multivaluearr = NULL;
- }
- return multivaluedic;
- }
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