快速创建一个对象的新实例并将其放入一个带有 TabBarView 按钮的数组中

Posted

技术标签:

【中文标题】快速创建一个对象的新实例并将其放入一个带有 TabBarView 按钮的数组中【英文标题】:creating a new instance of an object and putting it in an array with a button on a TabBarView with swift 【发布时间】:2018-07-09 04:18:35 【问题描述】:

我只是想创建一个标签栏视图,上面有一个按钮,它创建一个对象的实例,然后将它添加到一个数组中。我让它只使用一个视图控制器,但由于某种原因,当我添加一个标签栏控制器时,我终生无法让它工作。现在它正在抛出这个错误 - 致命错误:在展开可选值时意外发现 nil

这是我目前跨几个不同文件的所有代码

class ItemStore 

    var allItems = [Item]()



    @discardableResult func createItem() -> Item 
        let newItem = Item(name: "Item")

        allItems.append(newItem)

        return newItem
    

这就是项目,然后创建并将其添加到数组中

这是我的主视图控制器:

class ViewController: UIViewController 

    var itemStore: ItemStore

    required init?() 
    


    @IBAction func testButton(_ sender: Any) 

        print("This is working")
        itemStore.createItem() //this is where the error gets thrown
        print("We made it")

    

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        print("is this coming up")


    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

然后这就是我在应用程序委托中拥有的让我走到这一步的东西

class AppDelegate: UIResponder, UIApplicationDelegate 

var window: UIWindow?
var itemStore = ItemStore()


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    // Override point for customization after application launch.

    let tabController = window?.rootViewController as? ViewController
    tabController?.itemStore = itemStore

    return true

我确实有一个 UITabController 的文件.. 但它现在是空的。我尝试了各种各样的事情,但我想我还没有得到它。

对此的任何帮助将不胜感激。

【问题讨论】:

AppDelegate 中,将didFinishLaunchingWithOptions 更新为if let tabController = window?.rootViewController as? ViewController tabController.itemStore = itemStore 并验证您是否能够将itemStore 分配给tabController 它让我这样做,但它仍然抛出同样的错误。 您是否确认进入了 if 条件并分配了 itemStore? 我在该行的开头添加了闭包和 if 语句,就像您在上面键入的一样。在加载应用程序并单击按钮之前,它没有引发错误。然后它给了我和我上面写的一样的错误。 快速修复崩溃的方法是将ViewController 中的itemStore 设为var itemStore: ItemStore? 可选,并将调用更新为itemStore?.createItem() 【参考方案1】:

当您尝试强制解包可选变量但值不存在(nil)时,会发生上述错误。试试这个方法。


将 itemStore 设为 ViewController 中的可选变量

class ViewController: UIViewController 
    var itemStore: ItemStore?


并写下这一行

var itemStore = ItemStore()

里面 didFinishLaunchingWithOptions 并修改如下函数

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

    var itemStore = ItemStore()

    if let tabController = window?.rootViewController as? ViewController 
      //MAKE SURE THAT THIS `IF` condition is satisfied by putting a break point here
      tabController.itemStore = itemStore
    


    return true

而你的函数应该是这样的

@IBAction func testButton(_ sender: Any) 

    guard let itemStore = itemStore else 
     //item store is nil. probably not initialized properly from appDelegate.
     return //be safe
    
    //itemStore is not nil
    itemStore.createItem() //now error will not be thrown
    print("We made it")


如果您需要任何帮助,请告诉我

【讨论】:

【参考方案2】:

您的 ItemStore 对象似乎已初始化。

在您的ViewController 中声明您的 ItemStore:

var itemStore: ItemStore!

【讨论】:

我添加了它,但仍然出现同样的错误 - 你的意思是它已初始化? 在您的 ViewContoller 中,您可能会将其设为 nil,因此它会崩溃。所以用“!”运算符你不会有 nil 值。 @iosTeam 强行解包是个坏主意。更好的解决方案是使用 optional。

以上是关于快速创建一个对象的新实例并将其放入一个带有 TabBarView 按钮的数组中的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL - 调用包过程的新实例

创建智能和快速的精灵表

继续快速创建视图控制器的新实例

使用 JTextField 创建/编辑对象

PHP基于父类的现有实例创建子类的新实例

Serializable 指示一个类可以序列化;ICloneable支持克隆,即用与现有实例相同的值创建类的新实例(接口);ISerializable允许对象控制其自己的序列化和反序列化过程(接口)(