title: App crashes when UITableView loads from Core Data repetitively, bad pointer?
body: <p>I am making an app where the user selects a contact from the address book and adds it to a table view.</p>
  
  <p>I implemented this by creating an addressBook object, using a peoplePicker, storing the ABRecordID object in Core Data as an NSNumber, pulling the ABRecordID from Core Data and converting it into an ABRecordRef, then getting getting the kABPersonFirstNameProperty.</p>
  
  <p>When the app first loads, it runs fine. Names are selected and added to the Core Data database, but after 2-5 names are selected repetitively, the app crashes with "EXC_BAD_ACCESS(code=1, address=0x3...). This occurs in the cellForRowAtIndexPath tableView call towards the bottom of the code block.</p>
  
  <p>I cannot figure out why it crashes after working a few times. Sometimes it will work twice, others five times.</p>
  
  <p>Any help is greatly appreciated. Thank you!!</p>
  
  <p>Here is my code:</p>
  
  <pre><code>import UIKit
  import CoreData
  import AddressBook
  import AddressBookUI
  
  class ViewController: UIViewController, UITableViewDataSource, ABPeoplePickerNavigationControllerDelegate {
  
  @IBOutlet weak var tableView: UITableView!
  
  var contacts = [NSManagedObject]()
  
  @IBAction func addContact(sender: AnyObject) {
  
      // nav controller
      let picker = ABPeoplePickerNavigationController()
  
      // delegate so we can get the selected contact and info
      picker.peoplePickerDelegate = self
  
      // make only some people selectable, others grayed out
      //picker.predicateForEnablingPerson = NSPredicate(format: "%K like %@", ABPersonFamilyNameProperty, "Neuburg")
  
      // make sure we can see contact info
      picker.predicateForSelectionOfPerson = NSPredicate(value:true)
  
      // all done
      self.presentViewController(picker, animated:true, completion:nil)
  
  }
  
  // called when user picks a contact to get name
  func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, didSelectPerson contact: ABRecord!) {
  
      // ABRecordRefID object to use and store
      let contactABRecordID: Int32 = ABRecordGetRecordID(contact)
  
      // save the contact into Core Data
      self.saveContact(contactABRecordID)
  
      // reload data to table
      self.tableView.reloadData()
  }
  
  func saveContact(contactABRecordID: Int32) {
  
      // get access to managedObjectContext through the app delegate
      let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
  
      let managedContext = appDelegate.managedObjectContext!
  
      // create new managed object and instert into the managed object context
      let entity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: managedContext)
  
      let contact = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
  
      let wrapper = NSNumber(int: contactABRecordID)
  
      // set abrecordid attribute for NSMangedObject using KVC
      contact.setValue(wrapper, forKey: "abRecordID")
  
      // commit changes to person and save to disk
      var error: NSError?
      if !managedContext.save(&amp;error) {
          println("Could not save \(error), \(error?.userInfo)")
      }
  
      // append the new person to contacts database
      contacts.append(contact)
  
  }
  
  // fetch data from Core Data
  override func viewWillAppear(animated: Bool) {
      super.viewWillAppear(animated)
  
      // pull up app delegate and grab a ref to managed object context
      let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
  
      let managedContext = appDelegate.managedObjectContext!
  
      // fetch data from the database
      let fetchRequest = NSFetchRequest(entityName: "Contact")
  
      // create error var
      var error: NSError?
  
      // return an array of managed objects that meets critera from fetch request
      let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &amp;error) as [NSManagedObject]?
  
      // make sure fetch worked
      if let results = fetchedResults {
          contacts = results
      } else {
          println("Could not fetch \(error), \(error!.userInfo)")
      }
  
  }
  
  // MARK: - people picker protocol
  
  // address book object
  var addressBook : ABAddressBook!
  
  // check to see if app has access to contacts
  func determineStatus() -&gt; Bool {
  
      // assign status of access
      let status = ABAddressBookGetAuthorizationStatus()
  
      // handle status
      switch status {
      case .Authorized:
          // create address book if authoriezed
          return self.createAddressBook()
      case .NotDetermined:
          // ask for permission if haven't answered
          var ok = false
          ABAddressBookRequestAccessWithCompletion(nil) {
              (granted:Bool, err:CFError!) in
              dispatch_async(dispatch_get_main_queue()) {
                  if granted {
                      ok = self.createAddressBook()
                  }
              }
          }
          // proceed if access is granted
          if ok == true {
              return true
          }
          // otherwise return false
          self.addressBook = nil
          return false
          // if access is restricted
      case .Restricted:
          self.addressBook = nil
          return false
      case .Denied:
          // new iOS 8 feature: sane way of getting the user directly to the relevant prefs
          // I think the crash-in-background issue is now gone
          let alert = UIAlertController(title: "Need Authorization", message: "Wouldn't you like to authorize this app to use your Contacts?", preferredStyle: .Alert)
          alert.addAction(UIAlertAction(title: "No", style: .Cancel, handler: nil))
          alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: {
              _ in
              let url = NSURL(string:UIApplicationOpenSettingsURLString)!
              UIApplication.sharedApplication().openURL(url)
          }))
          self.presentViewController(alert, animated:true, completion:nil)
          self.addressBook = nil
          return false
      }
  }
  
  // create address book to use if granted access
  func createAddressBook() -&gt; Bool {
  
      // return true if created successfully
      if self.addressBook != nil {
          return true
      }
  
      // handle errors
      var err : Unmanaged&lt;CFError&gt;? = nil
      let addressBook : ABAddressBook? = ABAddressBookCreateWithOptions(nil, &amp;err).takeRetainedValue()
      if addressBook == nil {
          println(err)
          self.addressBook = nil
          return false
      }
  
      // assign addresss book with error then return
      self.addressBook = addressBook
      return true
  }
  
  // when app opens. make sure we have permission for contacts
  override func viewDidAppear(animated: Bool) {
  
      super.viewDidAppear(animated)
  
  }
  
  // =========
  
  // MARK: - table view protocol
  
  // table will have as many rows as contacts in array
  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
  
      // number of contacts in contacts array
      return contacts.count
  }
  
  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
  
      // each individual cell
      let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
  
      // contact is one of contacts in database
      let contact = contacts[indexPath.row]
  
      // get ABRecordID
      let wrapper: NSNumber = contact.valueForKey("abRecordID")! as NSNumber
  
      // turn wrapper into Int32 type
      let contactABRecordID: Int32 = Int32(wrapper.integerValue)
  
      // ERROR COMES HERE!!!! get person with record ID
      let personABRecordRef: ABRecordRef = ABAddressBookGetPersonWithRecordID(addressBook, contactABRecordID).takeRetainedValue() as ABRecordRef
  
      // get name from person with record ref
      let firstName: String = ABRecordCopyValue(personABRecordRef, kABPersonFirstNameProperty).takeRetainedValue() as String
  
      // grab name attribute from managed object
      cell.textLabel!.text = firstName
  
      // give cell to table
      return cell
  
  }
  
  // =========
  
  // MARK: - standard code
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      // determine if we have access to contacts
      self.determineStatus()
  
      // bring up a box in front if we don't
      NSNotificationCenter.defaultCenter().addObserver(self, selector: "determineStatus", name: UIApplicationWillEnterForegroundNotification, object: nil)
  
      // set the title
      title = "My People"
  
      // register UITableViewCell with tableView
      tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
  }
  
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }
  
  // =========
  
  }
  </code></pre>
  
  <p><strong>SOLVED!</strong></p>
  
  <p>Here is what I did. I needed to use an unmanged abperson ref and unwrap it.</p>
  
  <pre><code>func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
  
      // each individual cell
      let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
  
      // contact is one of contacts in database
      let contact = contacts[indexPath.row]
  
      // grab name attribute from managed object
      cell.textLabel!.text = getContactInfoFromCoreData(contact: contact)
  
      // give cell to table
      return cell
  
  }
  
  // =========
  
  // MARK: - get contact from Core Data
  
  func getContactInfoFromCoreData(#contact: NSManagedObject) -&gt; String {
  
      // get ABRecordID
      let wrapper: NSInteger = contact.valueForKey("abRecordID")! as NSInteger
  
      // turn wrapper into Int32 type
      let contactABRecordID: ABRecordID = Int32(wrapper)
  
      // get person ref with record ID
      let unmanagedPersonABRecordRef: Unmanaged&lt;ABRecordRef&gt;? = ABAddressBookGetPersonWithRecordID(addressBook, contactABRecordID)
  
      // unwrap optional ref to get real ref
      if let personRefToUse: ABRecordRef = unmanagedPersonABRecordRef?.takeUnretainedValue() {
  
          // use unwrapped ref to get property
          let firstName: String = ABRecordCopyValue(personRefToUse, kABPersonFirstNameProperty).takeRetainedValue() as String
  
          // return to table view
          return firstName
  
      }
  
      // not good
      return "Something went wrong"
  
  }
  
  // =========
  </code></pre>