4

I'm getting an intermittent crash when sorting an array and I've been unable to reproduce it on demand and unable to squash the issue. Here is the crash:

Crashed: com.apple.root.background-qos XC_BAD_ACCESS KERN_INVALID_ADDRESS 0x003400010efebbe8

specialized Array._createNewBuffer(bufferIsUnique:minimumCapacity:growForAppend:) + 4341522208

See code I believe is causing crash below (I think it's a thread issue) and I believe it's happening on the sort. Any help on this matter would be greatly appreciated! I've been struggling with this one for several days now. If you require any further information, please let me know. Thanks in advance:

func getPopCultureNews(completion: @escaping () -> Void) {
    let group = DispatchGroup()
    
    var items = [NewsItem]()
    
    for feed in NewsManager.shared.popCultureFeedUrls {
        group.enter()
        
        if let feedURL = URL(string: feed) {
            let parser = FeedParser(URL: feedURL)
            parser.parseAsync(queue: .global(qos: .background)) { (result) in
                switch result {
                case .success(let feed):
                    switch feed {
                    case let .atom(feed):
                        if let entries = feed.entries {
                            entries.forEach { (entry) in
                                let item = NewsItem(atomEntry: entry, rssEntry: nil, jsonEntry: nil)
                                if item.hasImage() {
                                    items.append(item)
                                }
                            }
                        }
                    case let .rss(feed):
                        if let entries = feed.items {
                            entries.forEach { (entry) in
                                let item = NewsItem(atomEntry: nil, rssEntry: entry, jsonEntry: nil)
                                if item.hasImage() {
                                    items.append(item)
                                }
                            }
                        }
                    case let .json(feed):
                        if let entries = feed.items {
                            entries.forEach { (entry) in
                                let item = NewsItem(atomEntry: nil, rssEntry: nil, jsonEntry: entry)
                                if item.hasImage() {
                                    items.append(item)
                                }
                            }
                        }
                    }
                case .failure(let error):
                    print(error)
                }
                
                items = items.sorted(by: { $0.getPublishedDate().compare($1.getPublishedDate()) == .orderedDescending })
                group.leave()
            }
        }
    }
    
    group.notify(queue: DispatchQueue.global(qos: .background)) {
        NewsManager.shared.popCultureItems = items
        completion()
    }
}
Mike Simz
  • 3,976
  • 4
  • 26
  • 43

1 Answers1

0

Looks like var items = [NewsItem]() should be thread-safe. Check this one for for more details Create thread safe array in Swift

Also, I'll suggest you make sorting once, for example in group.notify, instead of sorting in each iteration.

Andrew
  • 331
  • 1
  • 6
  • I initially had the sorting once (in group.notify), but that seemed to increase the crash frequency. I'll look into your link on creating thread safe array – Mike Simz Nov 24 '20 at 15:29