一つは、奇妙なランタイムエラーのクラッシュを引き起こしています私はエラーが発生します。スウィフト2〜3移行エラー(libcの++ abi.dylib:タイプNSExceptionのキャッチされない例外で終了)、それはスウィフト2に</p> <p>しなかったとき、私のコントローラの
のlibC++ abi.dylib:NSExceptionタイプのキャッチされない例外で終了
私はすべての私のインターフェイスビルダー要素がフックアップしたことを示すスクリーンショットを添付。
エラーが発生した場所を確認するためにいくつかの実験を行いましたが、おそらくtextViewを設定することに関連すると思われますが、わかりません。
1.)コンソールメッセージがprint("Draw Undo HTML")
の後に停止することに注意してください。もともと、私はコンソールメッセージprint("Set attributed text accordingly")
を見たことがないので、エラーは回線に関連していると思っていました。私は、エラーがまだ発生しますラインincrementListTextView.attributedText = html.html2AttributedString
をコメントアウトした場合
2)は、それが起こる前に、ちょうど残りのコードが実行されるけれども判明します。非常に奇妙ですが、エラーが最初にその行の周りに表示されるように見えますが、私はTextViewに関連していると思っていますが、何ができるかは不明です。
このシナリオの画像も添付されています。
InventoryItemController.Swift(完全なファイル参照)
//
// InventoryItemController.swift
// Inventory Counter
//
// Created by Joseph Astrahan on 4/3/16.
// Copyright © 2016 Joseph Astrahan. All rights reserved.
//
import UIKit
import CoreData
class InventoryItemController: UIViewController, UITextFieldDelegate {
var inventoryItem : Inventory?
var m_incrementAmount = 0 //amount it will increment everytime you press (+)
var m_itemHistory = [Int]() //create array to store undo/redo history
var m_undoIndex = 0
@IBOutlet weak var inventoryBarCodeLabel: UILabel!
@IBOutlet weak var inventoryTotalLabel: UILabel!
//List of increments
@IBOutlet weak var incrementListTextView: UITextView!
//Amount to increment by
@IBOutlet weak var incrementAmountTextField: UITextField!
@IBOutlet weak var inventoryNameNavItem: UINavigationItem!
@IBAction func resetBarButtonAction(_: UIBarButtonItem) {
//Present 'Are you sure?' Dialog & Reset Vars.
// create the alert in local scope (no need for weak or unowned reference to self in closures)
let alert = UIAlertController(title: "Are You Sure?", message: "This will delete all the counts you have done.", preferredStyle: UIAlertControllerStyle.alert)
// add an action (button)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: { action in
self.resetTotals()
}))
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
}
func resetTotals(){
print("resetting...")
m_itemHistory = [Int]()
m_itemHistory.append(0)//first count is always 0 after reset.
m_undoIndex = 0 //set back to 0
updateTotal()//update total and save to disk.
print("reset!...")
}
@IBAction func addInventoryButtonAction(_: UIButton) {
//When you add you have to first trim the array of everything that was after it. The redo history is now gone.
let slice = m_itemHistory[0...m_undoIndex]
m_itemHistory = Array(slice)//create new int array from the slice
m_incrementAmount = Int(incrementAmountTextField.text!)!
m_itemHistory.append(m_incrementAmount)
m_undoIndex = m_undoIndex + 1 //add to the index, because undo always happens from last added~
//Update addCount on actual inventoryItem (save to database)
updateTotal()
}
@IBAction func undoButtonAction(_: UIButton) {
print("undo")
m_undoIndex = m_undoIndex - 1
updateTotal()
}
@IBAction func redoButtonAction(_: UIButton) {
print("redo")
m_undoIndex = m_undoIndex + 1
updateTotal()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField){
textField.resignFirstResponder()
}
func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginViewController.dismissKeyboard))
self.view.addGestureRecognizer(tap)
print("Showing Inventory Item In Question")
print(inventoryItem)
print("Inventory Name="+(inventoryItem?.name!)!)
//inventoryNameLabel.text = inventoryItem.name!
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//add observer for contentSize so it centers vertically
incrementListTextView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.new, context: nil)
//Draw inventory name & barcode
inventoryNameNavItem.title = inventoryItem?.name
inventoryBarCodeLabel.text = inventoryItem?.barcode
//Load first time only when view appears to set default
m_itemHistory.append(Int((inventoryItem?.addCount!)!))//add initial value of last 'count'
m_undoIndex = 0 //reset to start.
updateTotal() //updates total to screen
print("Finished UpdateTotal, Should be Showing Screen Now")
}
func updateTotal(){
//Get the max Index we can count to -1 (because arrays are 0 indexed)
let historyTotalMaxIndex = m_itemHistory.count - 1
print("historyTotalCheck: HistoryTotalMaxIndex=\(historyTotalMaxIndex)")
//Current state of undoIndex
print("Init: m_undoIndex =\(m_undoIndex)")
//Do checks to prevent out of index bounds.
if(m_undoIndex<0){
m_undoIndex = 0
}
if(m_undoIndex>historyTotalMaxIndex){
m_undoIndex = historyTotalMaxIndex
}
//After modifying...
print("Current: m_undoIndex =\(m_undoIndex)")
//Draw HTML
var html = "<html><font size=\"5\"><font color=\"#008800\"><center>"
for index in 0...m_undoIndex {
let increment = m_itemHistory[index]
html = html + "+\(increment), "
}
html = html + "</center></font></font></html>"
print(html)
print("Draw Undo HTML")
incrementListTextView.attributedText = html.html2AttributedString
print("Set attributed text accordingly")
//get sum of itemHistory
let slice = m_itemHistory[0...m_undoIndex] //returns slice of the array we want.
let sumArray = Array(slice)//create new int array from the slice
print("SumArray Created")
let sum = sumArray.reduce(0, +) //now we can sum up that new sliced array
inventoryItem?.addCount = sum as NSNumber? //set the add count
print("Reduced the Array")
//reset html to different now
html = "<font size=\"10\"><center>Current: \(inventoryItem?.currentCount!) , <font color=\"#008800\"> Counted: \(inventoryItem?.addCount!)</font></center></font>"
inventoryTotalLabel.attributedText = html.html2AttributedString
print("save the context")
//Save the changes
(UIApplication.shared.delegate as! AppDelegate).saveContext()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//have to remove or will crash
incrementListTextView.removeObserver(self, forKeyPath: "contentSize")
}
/// Force the text in a UITextView to always center itself.
func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutableRawPointer) {
let textView = object as! UITextView
var topCorrect = (textView.bounds.size.height - textView.contentSize.height * textView.zoomScale)/2
topCorrect = topCorrect < 0.0 ? 0.0 : topCorrect;
textView.contentInset.top = topCorrect
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension String {
var html2AttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return nil }
do {
return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch let error as NSError {
print(error.localizedDescription)
return nil
}
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}
プロジェクトにlibC++。tbdファイルを追加しましたか? –
どうすればいいですか?または私がしたかどうか私はどのように知っていますか? –
これを一度試してみてください。プロジェクト - >一般 - >リンクされたフレームワークとバイナリ - > CLick ON +をクリックし、libC++を検索します。tbd - > add –