Swift中ABAddressBook iOS 8中的内存泄漏

时间:2016-06-09 20:27:37

标签: ios swift memory-leaks abaddressbook

我正在iOS 8中实现let some-list [["Hi" 52] ["C" 0] ["Hc" 60] ["Hd" 1]] foreach some-list [ let variable (first ?) let value (second ?) run (word "set " variable " " value) ] ,我开始创建一个示例项目来开始。我使用Single View Application模板创建了项目。在ABAddressBook viewDidAppear的{​​{1}}我添加了以下代码:

ViewController.swift

这是我唯一的代码,应用程序正在泄漏!我正在运行Leaks工具,它没有给出应用程序泄漏原因的足够好的背景信息。

泄漏工具快照 Memory leaks tool snapshot

调用树快照

Memory leak call tree snapshot

泄漏周期快照

Memory leak cycle snapshot

我不发布应该发布的内容吗?此外,我无法致电ViewController,因为我已启用ARC。

1 个答案:

答案 0 :(得分:0)

我无法复制,但是为了它的价值,以下产生了没有泄漏:

var addressBook: ABAddressBookRef?

func extractABAddressBookRef(abRef: Unmanaged<ABAddressBookRef>!) -> ABAddressBookRef? {
    if let ab = abRef {
        return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue()
    }
    return nil
}

func fetchAllContacts(completion: ((contacts: [String]?) -> Void)?) {
    let authorizationStatus = ABAddressBookGetAuthorizationStatus()
    switch authorizationStatus {
    case .NotDetermined:
        print("requesting access...")
        var errorRef: Unmanaged<CFError>? = nil
        addressBook = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
        ABAddressBookRequestAccessWithCompletion(addressBook, { [weak self] success, error in
            if success {
                completion?(contacts: self?.getContactNames())
            }
            else {
                print("error")
                completion?(contacts: nil)
            }
        })
    case .Denied, .Restricted:
        print("access denied")
        completion?(contacts: nil)
    case .Authorized:
        print("access granted")
        completion?(contacts: self.getContactNames())
    }
}

func getContactNames() -> [String]? {
    var errorRef: Unmanaged<CFError>?
    addressBook = extractABAddressBookRef(ABAddressBookCreateWithOptions(nil, &errorRef))
    let contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
    print("records in the array \(contactList.count)")

    return contactList.map({ (record: AnyObject) -> String in
        let contactRef: ABRecordRef = record
        let contactName: String = ABRecordCopyCompositeName(contactRef).takeRetainedValue() as String
        return contactName
    })
}

override func viewDidLoad() {
    super.viewDidLoad()

    fetchAllContacts { (contacts) in
        print("fetched contacts \(contacts)")
    }
}