Reputation: 4910
When compiling my project the compiler gets stuck on this class, after about 5 minutes of attempting to build I get a message telling me I'm out of system memory and to close some apps to continue. Is there something in this code which could cause the compiler to crash?
I'm using XCode9, seeing as my entire computer is crashing could this be a fault with XCode?
import UIKit
class ConferenceNumberViewController: UITableViewController, UINavigationControllerDelegate {
let sections = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
let countries = CallIn.Data.allCountries
var indexedCountries =
[
"A": [String](),
"B": [String](),
"C": [String](),
"D": [String](),
"E": [String](),
"F": [String](),
"G": [String](),
"H": [String](),
"I": [String](),
"J": [String](),
"K": [String](),
"L": [String](),
"M": [String](),
"N": [String](),
"O": [String](),
"P": [String](),
"Q": [String](),
"R": [String](),
"S": [String](),
"T": [String](),
"U": [String](),
"V": [String](),
"W": [String](),
"X": [String](),
"Y": [String](),
"Z": [String]()
]
var countryNumberIndex: Int = 0
var indexedConferenceNumbers = CallIn.Data.indexedConferenceNumbers
var selectedConferenceNumber: CallIn.ConferenceNumber!
override func viewDidLoad() {
super.viewDidLoad()
countryAndConference = true
// Do any additional setup after loading the view.
//hide back button according to design
navigationItem.setHidesBackButton(true, animated: false)
for section in sections {
for country in countries {
let searchCharacter: Character = section.characters.first!
let countryCheck: Character = country.characters.first!
let compare = countryCheck == searchCharacter
if compare {
indexedCountries[section]!.append(country)
}
}
}
// indexedConferenceNumbers = indexedConferenceNumbers.sort(sortFunc) // moved the sorting to the Data class
}
/*func sortFunc(num1: CallIn.ConferenceNumber, num2: CallIn.ConferenceNumber) -> Bool {
return num1.country == num2.country ? (num1.typeOfNumber > num2.typeOfNumber) : (num1.country < num2.country)
}*/ // moved the sorting to the Data class
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// custom section view
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView //recast your view as a UITableViewHeaderFooterView
header.contentView.backgroundColor = Design.Colours.lightBlue // make the background light grey
if (accessibilityON){
header.textLabel!.font = UIFont(descriptor: UIFontDescriptor.regularDescriptor(UIFontTextStyle.body.rawValue), size: 0)
} else { header.textLabel!.font = UIFont.systemFont(ofSize: 13)}
// header.textLabel!.textColor = Design.Colours.subtextDarkGrey //make the text dark grey
// header.textLabel!.font = UIFont.systemFontOfSize(13) // set size of text
//header.alpha = 0.5 //make the header transparent
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CountryCell", for: indexPath)
let country = cell.viewWithTag(511) as! UILabel
let number = cell.viewWithTag(512) as! UILabel
let type = cell.viewWithTag(513) as! UILabel
// we have to calculate the index (jump) because the conference numbers list is single array (there are no sections)
var jump = 0
for index in 0...(indexPath as NSIndexPath).section {
(index == (indexPath as NSIndexPath).section) ? (jump = jump + (indexPath as NSIndexPath).row) : (jump = jump + indexedCountries[sections[index]]!.count)
}
country.text = indexedConferenceNumbers[jump].country
number.text = indexedConferenceNumbers[jump].conferenceNumber
type.text = indexedConferenceNumbers[jump].typeOfNumber
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return indexedCountries[sections[section]]!.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if (countriesPerSection("\(sections[section])").count == 0) {
return nil
}
return sections[section] as String
}
//index on the right side of the screen
override func sectionIndexTitles(for tableView: UITableView) -> ([String]!){
return self.sections
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if (countriesPerSection("\(sections[section])").count == 0) {
return 0.1
}
return 30.0
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let indexPath = self.tableView.indexPathForSelectedRow {
tableView.deselectRow(at: indexPath, animated: true)
let selectedCell = tableView.cellForRow(at: indexPath) as UITableViewCell!
let country = selectedCell?.contentView.viewWithTag(511) as! UILabel
let number = selectedCell?.contentView.viewWithTag(512) as! UILabel
let type = selectedCell?.contentView.viewWithTag(513) as! UILabel
// Set the number to be passed to SettingDetailsViewController after the unwind segue.
selectedConferenceNumber = CallIn.ConferenceNumber(country: country.text!, conferenceNumber: number.text!, typeOfNumber: type.text!, isoCode: "")
}
}
private func countriesPerSection(_ section: String) -> [String] {
var matches = [String]()
for country in indexedCountries["\(section)"]! {
matches.append(country)
}
return matches
}
private func conferenceNumbersPerCountry(_ country: String) -> Array<CallIn.ConferenceNumber> {
var matches = Array<CallIn.ConferenceNumber>()
for numbers in indexedConferenceNumbers {
if numbers.country == country {
let conferenceNumber = CallIn.ConferenceNumber(country: numbers.country, conferenceNumber: numbers.conferenceNumber, typeOfNumber: numbers.typeOfNumber, isoCode: numbers.isoCode)
matches.append(conferenceNumber)
}
}
return matches
}
@IBAction private func goBack(_ sender: UIBarButtonItem) {
self.navigationController!.popViewController(animated: true)
}
}
Upvotes: 3
Views: 74
Reputation: 318914
The Swift compiler is probably having issues with such a large dictionary and trying to infer the proper type for the indexedCountries
variable.
One solution is to provide the type:
var indexedCountries: [String, [String]] =
A better solution is to avoid such code. Change the hardcoded dictionary to just the following:
var indexedCountries = [String, [String]]()
And then in viewDidLoad
you can populate it:
for letter in sections {
indexedCountries[letter] = [String]()
}
This avoid a lot of extra typing, avoids potential typos, and makes the compiler's job a lot simple (faster compiling).
You may also benefit from updating the declaration for sections
to be:
let sections: [String] = [ "A", ... ]
Upvotes: 3
Reputation: 4910
Downgrading to XCode 8.3.3 fixed this for me. I'll edit this answer if I find a work around for getting 9.0 or 9.1 to work.
Upvotes: 0