Skip to content

Instantly share code, notes, and snippets.

@mackoj
Created September 3, 2018 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mackoj/33e611b7bf349d8b1f5e45574679ca1d to your computer and use it in GitHub Desktop.
Save mackoj/33e611b7bf349d8b1f5e45574679ca1d to your computer and use it in GitHub Desktop.
import UIKit
import Foundation
struct AllocDeallocTester {
struct AllocationResult : CustomDebugStringConvertible {
let className : String
var pointerNumber : Int = 0
var numberOfMissDealloc : Int = 0
var numberOfValidDealloc : Int = 0
init(className inputClassName: String) {
self.className = inputClassName
}
var debugDescription: String {
get {
let state = numberOfMissDealloc == 0 ? "👍🏻" : "👎🏻"
return "\n\(state)\(className)[\(pointerNumber)] nonDealloc(\(numberOfMissDealloc)) Dealloc(\(numberOfValidDealloc))"
}
}
}
enum AllocType {
case alloc
case dealloc
}
struct LigneResult {
let className : String
let pointer : String
var type : AllocType = .alloc
}
static func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let nsString = text as NSString
let range = NSRange(location: 0, length: nsString.length)
let results = regex.matches(in: text, options: [], range: range)
var output : [String] = []
guard
let first = (results.first?.range(at: 1)),
let second = (results.first?.range(at: 2)),
let third = (results.first?.range(at: 3))
else { return [] }
output.append(nsString.substring(with: first))
output.append(nsString.substring(with: second))
output.append(nsString.substring(with: third))
return output
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
static func getLigneData(inputString : String) -> LigneResult? {
let regexPattern = "-- (alloc|dealloc) \\d+ -- @\"<(.*): (.*)>"
let res = matches(for: regexPattern, in: inputString)
if res.count != 3 {
return nil
}
let alloc = (res[0] == "dealloc") ? AllocType.dealloc : AllocType.alloc
let className = res[1]
let pointer = res[2]
return LigneResult(className: className, pointer: pointer, type: alloc)
}
static func filterByPointer(lignes : [LigneResult]) -> [String:[LigneResult]] {
var pointerOriented : [String:[LigneResult]] = [:]
for aLigne in lignes {
if let _ = pointerOriented[aLigne.pointer] {
pointerOriented[aLigne.pointer]?.append(aLigne)
} else {
pointerOriented[aLigne.pointer] = [aLigne]
}
}
return pointerOriented
}
static func filterByClassName(lignes : [LigneResult]) -> [String:[String : [LigneResult]]] {
var pointerOriented : [String:[LigneResult]] = [:]
for aLigne in lignes {
if let _ = pointerOriented[aLigne.className] {
pointerOriented[aLigne.className]?.append(aLigne)
} else {
pointerOriented[aLigne.className] = [aLigne]
}
}
var res : [String:[String : [LigneResult]]] = [:]
for (className, lignes) in pointerOriented {
res[className] = filterByPointer(lignes :lignes)
}
return res
}
static func transformLigneDataToResult(lignes : [LigneResult]) -> [AllocationResult] {
var output : [AllocationResult] = []
let filteredLignes = filterByClassName(lignes: lignes)
for (className, pointerLigne) in filteredLignes {
var allocR = AllocationResult(className: className)
allocR.pointerNumber = pointerLigne.count
var numberOfValidDealloc = 0
var numberOfMissDealloc = 0
for (_, lignes) in pointerLigne {
let allocs = lignes.reduce(0, { (res, l) in
if (l.type == .alloc) {
return res + 1
}
return res + 0
})
let deallocs = lignes.reduce(0, { (res, l) in
if (l.type == .dealloc) {
return res + 1
}
return res + 0
})
if allocs - deallocs == 0 {
numberOfValidDealloc = numberOfValidDealloc + 1
} else {
numberOfMissDealloc = numberOfMissDealloc + 1
}
}
allocR.numberOfValidDealloc = numberOfValidDealloc
allocR.numberOfMissDealloc = numberOfMissDealloc
output.append(allocR)
}
return output
}
public static func generateAllocationResult(inputTexte : String) -> [AllocationResult] {
let lines = inputTexte.components(separatedBy: .newlines)
let results = lines.compactMap(getLigneData)
let allocationsStats = transformLigneDataToResult(lignes : results)
return allocationsStats
}
}
let inputAllocation = """
-- alloc 1 -- @"<PagesJaunes.TabBarViewer: 0x7fc789803600>" 0x0
-- alloc 2 -- @"<UINavigationController: 0x7fc788001a00>" 0x0
-- alloc 3 -- @"<UINavigationController: 0x7fc7880aa800>" 0x0
-- alloc 4 -- @"<UINavigationController: 0x7fc789822a00>" 0x0
-- alloc 5 -- @"<PagesJaunes.HomeViewer: 0x7fc787d0ae40>" 0x0
-- alloc 6 -- @"<PagesJaunes.HPShortcutViewer: 0x7fc78a11eab0>" 0x0
-- alloc 7 -- @"<PagesJaunes.HPInterruptedActionsViewer: 0x7fc787e13d50>" 0x0
-- alloc 8 -- @"<PagesJaunes.HPEngagementViewer: 0x7fc787e13690>" 0x0
-- alloc 9 -- @"<APMBadgeViewController: 0x7fc787c1ba20>" 0x0
-- alloc 10 -- @"<PagesJaunes.HistoricViewer: 0x7fc787d11150>" 0x0
-- alloc 11 -- @"<APMBadgeViewController: 0x7fc78a1aa8a0>" 0x0
-- alloc 12 -- @"<UIViewController: 0x7fc787e7bcc0>" 0x0
-- alloc 13 -- @"<PagesJaunes.InternalFDViewController: 0x7fc78c07e000>" 0x0
-- alloc 14 -- @"<PagesJaunes.FDModulesViewController: 0x7fc787c55d40>" 0x0
-- alloc 15 -- @"<UIViewController: 0x7fc787c60640>" 0x0
-- alloc 16 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787d75620>" 0x0
-- alloc 17 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc78a1da260>" 0x0
-- alloc 18 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787c75800>" 0x0
-- alloc 19 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787c78c10>" 0x0
-- alloc 20 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc78a1dd1e0>" 0x0
-- alloc 21 -- @"<PagesJaunes.SimpleModuleViewControllerStickerTop: 0x7fc787d71320>" 0x0
-- alloc 22 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc78a1e0710>" 0x0
-- alloc 23 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787f1b940>" 0x0
-- alloc 24 -- @"<PagesJaunes.SimpleModuleViewControllerStickerTop: 0x7fc787e99b00>" 0x0
-- alloc 25 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787e9d210>" 0x0
-- alloc 26 -- @"<PagesJaunes.SimpleModuleViewController: 0x7fc787c714e0>" 0x0
-- alloc 27 -- @"<APMBadgeViewController: 0x7fc787c39970>" 0x0
-- alloc 28 -- @"<UIViewController: 0x7fc78a2183a0>" 0x0
-- alloc 29 -- @"<APMBadgeViewController: 0x7fc787c6bba0>" 0x0
-- alloc 30 -- @"<UIViewController: 0x7fc787d564e0>" 0x0
-- dealloc @"<APMBadgeViewController: 0x7fc787c1ba20>" 0x0
-- dealloc @"<APMBadgeViewController: 0x7fc78a1aa8a0>" 0x0
-- dealloc @"<UIViewController: 0x7fc787e7bcc0>" 0x0
-- dealloc @"<APMBadgeViewController: 0x7fc787c39970>" 0x0
-- dealloc @"<UIViewController: 0x7fc78a2183a0>" 0x0
-- dealloc @"<PagesJaunes.InternalFDViewController: 0x7fc78c07e000>" 0x0
-- dealloc @"<APMBadgeViewController: 0x7fc787c6bba0>" 0x0
-- dealloc @"<UIViewController: 0x7fc787d564e0>" 0x0
"""
let res = AllocDeallocTester.generateAllocationResult(inputTexte: inputAllocation)
print(res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment