【问题标题】:How to access elements from an NSObject in swift?如何快速访问 NSObject 中的元素?
【发布时间】:2016-10-01 12:57:57
【问题描述】:

我已经将一些变量设置为对象

import UIKit
class SpeedTestResult: NSObject {
    var testTime: NSDate?
}

然后在控制器中我设置这个对象并将它传递给一个类来存储它:

testResult.testTime = NSDate()
SpeedTestManager().addTestResult(testResult)

我需要存储这个对象,然后稍后在视图中访问其中的元素,这就是我所拥有的:

import Foundation
class SpeedTestManager : NSObject {
    var testResultArray = [NSObject]()
    func addTestResult(testResult: NSObject) {
        testResultArray.append(testResult)
        print("Printing testResultArray: \(testResultArray)")

    }
}

但是当我尝试打印我刚刚得到的对象时

Printing testResultArray: [<ProjectName.SpeedTestResult: 0x127b85e50>]

如何访问对象中的元素并存储该对象并检索它以供以后在视图中使用?

【问题讨论】:

    标签: ios swift swift2 local-storage nsobject


    【解决方案1】:
    class TestResult : NSObject, NSSecureCoding {
        var testTime: NSDate?
    
        override init() {
            super.init()
        }
    
        @objc required init?(coder decoder: NSCoder) {
            self.testTime = decoder.decodeObjectForKey("testTime") as? NSDate
        }
    
        @objc func encodeWithCoder(encoder: NSCoder) {
            encoder.encodeObject(self.testTime, forKey: "testTime")
        }
    
        @objc static func supportsSecureCoding() -> Bool {
            return true
        }
    
        override var description: String {
            return String.init(format: "TestResult: %@", self.testTime ?? "null")
        }
    }
    
    class SpeedTestManager : NSObject, NSSecureCoding {
        var testResultArray = [NSObject]()
    
        func addTestResult(testResult: NSObject) {
            testResultArray.append(testResult)
            print("Printing testResultArray: \(testResultArray)")
        }
    
        override init() {
            super.init()
        }
    
        @objc func encodeWithCoder(encoder: NSCoder) {
            encoder.encodeObject(self.testResultArray, forKey: "testResultArray")
        }
    
        @objc required init?(coder decoder: NSCoder) {
            self.testResultArray = decoder.decodeObjectForKey("testResultArray") as! [NSObject]
        }
    
        @objc static func supportsSecureCoding() -> Bool {
            return true
        }
    
        override var description: String {
            return String.init(format: "SpeedManager: [%@]", self.testResultArray.map({"\($0)"}).joinWithSeparator(","))
        }
    }
    
    class TestViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
    
            let testResult = TestResult()
                testResult.testTime = NSDate()
    
            let speedManager = SpeedTestManager()
                speedManager.addTestResult(testResult)
    
            NSUserDefaults.standardUserDefaults().setObject(NSKeyedArchiver.archivedDataWithRootObject(speedManager), forKey: "speedManager")
            NSUserDefaults.standardUserDefaults().synchronize()
    
            if let archivedSpeedManager = NSUserDefaults.standardUserDefaults().objectForKey("speedManager") as? NSData {
                let unarchivedSpeedManager = NSKeyedUnarchiver.unarchiveObjectWithData(archivedSpeedManager)
                print("SpeedManager: \(unarchivedSpeedManager ?? "null")")
            }
            else {
                print("Failed to unarchive speed manager")
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是您可以做到的一种方法:

          import Foundation
      
          class SpeedTestResult: NSObject {
              var testTime: NSDate?
          }
      
          class SpeedTestManager : NSObject {
              var testResultArray = [NSObject]()
              func addTestResult(testResult: NSObject) {
                  testResultArray.append(testResult)
                  for result in testResultArray {
      //  This will crash if result is not a SpeedTestResult.
      //                print((result as! SpeedTestResult).testTime)
      //  This is better:
                     if let timeResult = result as? SpeedTestResult
                     {
                         print(timeResult.testTime)
                     }
                     else 
                     {
                         print("Not time type...")
                     }
                  }           
              }
          }
      
          var testResult = SpeedTestResult()
          testResult.testTime = NSDate()
          SpeedTestManager().addTestResult(testResult)
      

      这解决了您的具体问题,但这里还有一些其他问题:

      • 如果您打算仅将 SpeedTestResult 实例存储在 testResultArray,那为什么不把它做成类型 [SpeedTestResutl]()?
      • 如果您将在数组中存储不同类型的测试,那么如何 您发现NSObject 元素代表哪种类型的测试? 有一些方法......在上面的代码中,我们至少确保我们没有将错误类型的对象视为SpeedTestResult
      • 当您执行SpeedTestManager().addTestResult(testResult) 时,您不会 保留对SpeedTestManager 实例的引用。下一次 你打同样的电话,你会创造一个不同的 SpeedTestManager 实例。

      • 这不是真正的问题,但SpeedTestManager 不必 是NSObject 的子类,除非你想在 Objective-C。

      • 你可能不想打印testResultArray的内容 addTestResult() 方法。你可以有其他方法 访问数组。

      要将您的测试结果添加到同一个测试管理器,您可以:

      let myTestManager = SpeedTestManager()
      myTestManager.addTestResult(testResult)     
      // create other test results and add them ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-10
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多