Use DatabaseDictionary instead of NSDictionary. Work around a Swift memory leak with NSDictionary.
This commit is contained in:
parent
797c7cb0fb
commit
e04250f1b3
|
@ -40,31 +40,30 @@ extension Article {
|
|||
self.init(accountID: accountID, articleID: parsedItem.syncServiceID, feedID: feedID, uniqueID: parsedItem.uniqueID, title: parsedItem.title, contentHTML: parsedItem.contentHTML, contentText: parsedItem.contentText, url: parsedItem.url, externalURL: parsedItem.externalURL, summary: parsedItem.summary, imageURL: parsedItem.imageURL, bannerImageURL: parsedItem.bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, attachments: attachments, status: status)
|
||||
}
|
||||
|
||||
private func addPossibleStringChangeWithKeyPath(_ comparisonKeyPath: KeyPath<Article,String?>, _ otherArticle: Article, _ key: String, _ dictionary: NSMutableDictionary) {
|
||||
|
||||
private func addPossibleStringChangeWithKeyPath(_ comparisonKeyPath: KeyPath<Article,String?>, _ otherArticle: Article, _ key: String, _ dictionary: inout DatabaseDictionary) {
|
||||
if self[keyPath: comparisonKeyPath] != otherArticle[keyPath: comparisonKeyPath] {
|
||||
dictionary.addOptionalStringDefaultingEmpty(self[keyPath: comparisonKeyPath], key)
|
||||
dictionary[key] = self[keyPath: comparisonKeyPath] ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
func changesFrom(_ existingArticle: Article) -> NSDictionary? {
|
||||
func changesFrom(_ existingArticle: Article) -> DatabaseDictionary? {
|
||||
if self == existingArticle {
|
||||
return nil
|
||||
}
|
||||
|
||||
let d = NSMutableDictionary()
|
||||
var d = DatabaseDictionary()
|
||||
if uniqueID != existingArticle.uniqueID {
|
||||
d[DatabaseKey.uniqueID] = uniqueID
|
||||
}
|
||||
|
||||
addPossibleStringChangeWithKeyPath(\Article.title, existingArticle, DatabaseKey.title, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.contentHTML, existingArticle, DatabaseKey.contentHTML, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.contentText, existingArticle, DatabaseKey.contentText, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.url, existingArticle, DatabaseKey.url, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.externalURL, existingArticle, DatabaseKey.externalURL, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.summary, existingArticle, DatabaseKey.summary, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.imageURL, existingArticle, DatabaseKey.imageURL, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.bannerImageURL, existingArticle, DatabaseKey.bannerImageURL, d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.title, existingArticle, DatabaseKey.title, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.contentHTML, existingArticle, DatabaseKey.contentHTML, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.contentText, existingArticle, DatabaseKey.contentText, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.url, existingArticle, DatabaseKey.url, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.externalURL, existingArticle, DatabaseKey.externalURL, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.summary, existingArticle, DatabaseKey.summary, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.imageURL, existingArticle, DatabaseKey.imageURL, &d)
|
||||
addPossibleStringChangeWithKeyPath(\Article.bannerImageURL, existingArticle, DatabaseKey.bannerImageURL, &d)
|
||||
|
||||
// If updated versions of dates are nil, and we have existing dates, keep the existing dates.
|
||||
// This is data that’s good to have, and it’s likely that a feed removing dates is doing so in error.
|
||||
|
@ -91,27 +90,44 @@ extension Article {
|
|||
|
||||
extension Article: DatabaseObject {
|
||||
|
||||
public func databaseDictionary() -> NSDictionary? {
|
||||
|
||||
let d = NSMutableDictionary()
|
||||
public func databaseDictionary() -> DatabaseDictionary? {
|
||||
var d = DatabaseDictionary()
|
||||
|
||||
d[DatabaseKey.articleID] = articleID
|
||||
d[DatabaseKey.feedID] = feedID
|
||||
d[DatabaseKey.uniqueID] = uniqueID
|
||||
|
||||
d.addOptionalString(title, DatabaseKey.title)
|
||||
d.addOptionalString(contentHTML, DatabaseKey.contentHTML)
|
||||
d.addOptionalString(contentText, DatabaseKey.contentText)
|
||||
d.addOptionalString(url, DatabaseKey.url)
|
||||
d.addOptionalString(externalURL, DatabaseKey.externalURL)
|
||||
d.addOptionalString(summary, DatabaseKey.summary)
|
||||
d.addOptionalString(imageURL, DatabaseKey.imageURL)
|
||||
d.addOptionalString(bannerImageURL, DatabaseKey.bannerImageURL)
|
||||
|
||||
d.addOptionalDate(datePublished, DatabaseKey.datePublished)
|
||||
d.addOptionalDate(dateModified, DatabaseKey.dateModified)
|
||||
|
||||
return (d.copy() as! NSDictionary)
|
||||
if let title = title {
|
||||
d[DatabaseKey.title] = title
|
||||
}
|
||||
if let contentHTML = contentHTML {
|
||||
d[DatabaseKey.contentHTML] = contentHTML
|
||||
}
|
||||
if let contentText = contentText {
|
||||
d[DatabaseKey.contentText] = contentText
|
||||
}
|
||||
if let url = url {
|
||||
d[DatabaseKey.url] = url
|
||||
}
|
||||
if let externalURL = externalURL {
|
||||
d[DatabaseKey.externalURL] = externalURL
|
||||
}
|
||||
if let summary = summary {
|
||||
d[DatabaseKey.summary] = summary
|
||||
}
|
||||
if let imageURL = imageURL {
|
||||
d[DatabaseKey.imageURL] = imageURL
|
||||
}
|
||||
if let bannerImageURL = bannerImageURL {
|
||||
d[DatabaseKey.bannerImageURL] = bannerImageURL
|
||||
}
|
||||
if let datePublished = datePublished {
|
||||
d[DatabaseKey.datePublished] = datePublished
|
||||
}
|
||||
if let dateModified = dateModified {
|
||||
d[DatabaseKey.dateModified] = dateModified
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
public var databaseID: String {
|
||||
|
@ -160,35 +176,8 @@ extension Set where Element == Article {
|
|||
return self.map{ $0 as DatabaseObject }
|
||||
}
|
||||
|
||||
func databaseDictionaries() -> [NSDictionary]? {
|
||||
func databaseDictionaries() -> [DatabaseDictionary]? {
|
||||
|
||||
return self.compactMap { $0.databaseDictionary() }
|
||||
}
|
||||
}
|
||||
|
||||
private extension NSMutableDictionary {
|
||||
|
||||
func addOptionalString(_ value: String?, _ key: String) {
|
||||
|
||||
if let value = value {
|
||||
self[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
func addOptionalStringDefaultingEmpty(_ value: String?, _ key: String) {
|
||||
|
||||
if let value = value {
|
||||
self[key] = value
|
||||
}
|
||||
else {
|
||||
self[key] = ""
|
||||
}
|
||||
}
|
||||
|
||||
func addOptionalDate(_ date: Date?, _ key: String) {
|
||||
|
||||
if let date = date {
|
||||
self[key] = date as NSDate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,17 +29,8 @@ extension ArticleStatus: DatabaseObject {
|
|||
return articleID
|
||||
}
|
||||
|
||||
public func databaseDictionary() -> NSDictionary? {
|
||||
|
||||
let d = NSMutableDictionary()
|
||||
|
||||
d[DatabaseKey.articleID] = articleID
|
||||
d[DatabaseKey.read] = read
|
||||
d[DatabaseKey.starred] = starred
|
||||
d[DatabaseKey.userDeleted] = userDeleted
|
||||
d[DatabaseKey.dateArrived] = dateArrived
|
||||
|
||||
return (d.copy() as! NSDictionary)
|
||||
public func databaseDictionary() -> DatabaseDictionary? {
|
||||
return [DatabaseKey.articleID: articleID, DatabaseKey.read: read, DatabaseKey.starred: starred, DatabaseKey.userDeleted: userDeleted, DatabaseKey.dateArrived: dateArrived]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,13 +60,8 @@ extension Attachment: DatabaseObject {
|
|||
return attachmentID
|
||||
}
|
||||
|
||||
public func databaseDictionary() -> NSDictionary? {
|
||||
|
||||
let d = NSMutableDictionary()
|
||||
|
||||
d[DatabaseKey.attachmentID] = attachmentID
|
||||
d[DatabaseKey.url] = url
|
||||
|
||||
public func databaseDictionary() -> DatabaseDictionary? {
|
||||
var d: DatabaseDictionary = [DatabaseKey.attachmentID: attachmentID, DatabaseKey.url: url]
|
||||
if let mimeType = mimeType {
|
||||
d[DatabaseKey.mimeType] = mimeType
|
||||
}
|
||||
|
@ -79,15 +74,14 @@ extension Attachment: DatabaseObject {
|
|||
if let durationInSeconds = durationInSeconds {
|
||||
d[DatabaseKey.durationInSeconds] = NSNumber(value: durationInSeconds)
|
||||
}
|
||||
|
||||
return (d.copy() as! NSDictionary)
|
||||
return d
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Set where Element == Attachment {
|
||||
|
||||
func databaseDictionaries() -> [NSDictionary] {
|
||||
func databaseDictionaries() -> [DatabaseDictionary] {
|
||||
|
||||
return self.compactMap { $0.databaseDictionary() }
|
||||
}
|
||||
|
|
|
@ -48,12 +48,9 @@ extension Author: DatabaseObject {
|
|||
return authorID
|
||||
}
|
||||
|
||||
public func databaseDictionary() -> NSDictionary? {
|
||||
|
||||
let d = NSMutableDictionary()
|
||||
|
||||
d[DatabaseKey.authorID] = authorID
|
||||
public func databaseDictionary() -> DatabaseDictionary? {
|
||||
|
||||
var d: DatabaseDictionary = [DatabaseKey.authorID: authorID]
|
||||
if let name = name {
|
||||
d[DatabaseKey.name] = name
|
||||
}
|
||||
|
@ -66,8 +63,7 @@ extension Author: DatabaseObject {
|
|||
if let emailAddress = emailAddress {
|
||||
d[DatabaseKey.emailAddress] = emailAddress
|
||||
}
|
||||
|
||||
return (d.copy() as! NSDictionary)
|
||||
return d
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,9 +108,11 @@ private extension SearchTable {
|
|||
}
|
||||
|
||||
func insert(_ article: ArticleSearchInfo, _ database: FMDatabase) -> Int {
|
||||
let rowDictionary = NSMutableDictionary()
|
||||
rowDictionary.setObject(article.title ?? "", forKey: DatabaseKey.title as NSString)
|
||||
rowDictionary.setObject(article.bodyForIndex, forKey: DatabaseKey.body as NSString)
|
||||
let rowDictionary: DatabaseDictionary = [DatabaseKey.body: article.bodyForIndex, DatabaseKey.title: article.title ?? ""]
|
||||
// rowDictionary[DatabaseKey.title] = article.title ?? ""
|
||||
// rowDictionary[DatabaseKey.body] = article.bodyForIndex
|
||||
// rowDictionary.setObject(article.title ?? "", forKey: DatabaseKey.title as NSString)
|
||||
// rowDictionary.setObject(article.bodyForIndex, forKey: DatabaseKey.body as NSString)
|
||||
insertRow(rowDictionary, insertType: .normal, in: database)
|
||||
return Int(database.lastInsertRowId())
|
||||
}
|
||||
|
@ -168,12 +170,12 @@ private extension SearchTable {
|
|||
return
|
||||
}
|
||||
|
||||
let updateDictionary = NSMutableDictionary()
|
||||
var updateDictionary = DatabaseDictionary()
|
||||
if title != searchInfo.title {
|
||||
updateDictionary.setObject(title, forKey: DatabaseKey.title as NSString)
|
||||
updateDictionary[DatabaseKey.title] = title
|
||||
}
|
||||
if article.bodyForIndex != searchInfo.body {
|
||||
updateDictionary.setObject(article.bodyForIndex, forKey: DatabaseKey.body as NSString)
|
||||
updateDictionary[DatabaseKey.body] = article.bodyForIndex
|
||||
}
|
||||
updateRowsWithDictionary(updateDictionary, whereKey: DatabaseKey.rowID, matches: searchInfo.rowID, database: database)
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3d57e08e9d905c432e86a2544ccfb1390257aec2
|
||||
Subproject commit 92f72ec2c179a5cb5c1b69df8ab4d428d598c243
|
Loading…
Reference in New Issue