使用 Swift 将项目添加到 iOS 中的数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24128441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:44:23  来源:igfitidea点击:

Adding item to array in iOS with Swift

iosswiftios8xcode6

提问by Hyman Solomon

I am trying to add an item to my array (which was declared as a var), using anything that might work (+=, append, insert), however I keep getting the error 'Immutable value of type 'AnyObject[]' only has mutating members named 'append''.

我正在尝试将一个项目添加到我的数组(它被声明为var),使用任何可能起作用的东西(+=、追加、插入),但是我一直收到错误“'AnyObject[] 类型的不可变值'”具有名为“append”的变异成员。

Here is where the error occurs:

这是发生错误的地方:

func testSave(item : NSString, date : NSString){

    itemsArray.append(item) 

UPDATE: HERE IS THE FULL CODE:

更新:这是完整的代码:

import UIKit

class ToDoListTableViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate {
    var itemsArray = NSUserDefaults .standardUserDefaults().arrayForKey("items")
    var dateArray = NSUserDefaults .standardUserDefaults().arrayForKey("dates")



    override func viewDidLoad() {
        super.viewDidLoad()
        NSUserDefaults .standardUserDefaults().setObject("test", forKey: "items")
        NSUserDefaults .standardUserDefaults().setObject("test", forKey: "dates")

        self.itemsArray = NSUserDefaults .standardUserDefaults().arrayForKey("items")
        self.dateArray = NSUserDefaults .standardUserDefaults().arrayForKey("dates")
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

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

    // #pragma mark - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        if itemsArray{
            return itemsArray.count}
        else{
            return 0}
    }

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!{
        //variable type is inferred
        /*var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell

        if !cell {
            cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
        }

        //we know that cell is not empty now so we use ! to force unwrapping
        cell!.textLabel.text = self.itemsArray[indexPath.row] as String
        cell!.detailTextLabel.text = self.dateArray[indexPath.row] as String
        */
        let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:"Cell")

        if itemsArray{
            println("Working")
        cell.textLabel.text = itemsArray[indexPath.row] as String
        cell.detailTextLabel.text = dateArray[indexPath.row] as String
        }
        return cell
    }


    @IBAction func addItem(sender : UIBarButtonItem) {
        var alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: {(action: UIAlertAction!) in
            var stringText = alert.textFields[0].text
            var dateText = alert.textFields[0].text
            self .testSave(stringText, date: dateText)
            }))
        alert.addTextFieldWithConfigurationHandler(nil)
        self.presentViewController(alert, animated: true, completion: nil)
    }
    func testSave(item : NSString, date : NSString){

        itemsArray.append(item)

       /* NSUserDefaults .standardUserDefaults().setObject(item, forKey: "items")


        /*    NSUserDefaults .standardUserDefaults().setObject(stringText, forKey: "items")
        NSUserDefaults .standardUserDefaults().setObject(dateText, forKey: "dates")
        NSUserDefaults.standardUserDefaults().synchronize()
        */

        self.dateArray = NSUserDefaults .standardUserDefaults().arrayForKey("dates")
        self.tableView .reloadData() */
    }
    func alertviewClick(){

    }

}

回答by Dash

This works fine:

这工作正常:

var itemsArray = ["one", "two"]
func testSave(item : NSString, date : NSString){

    itemsArray.append(item)
}

testSave("three", "today")
itemsArray

回答by Cai

Problem is here:

问题在这里:

var itemsArray = NSUserDefaults.standardUserDefaults().arrayForKey("items")

See the Apple's document:

请参阅Apple的文档:

func arrayForKey(_ defaultName: String!) -> AnyObject[]!
  • The returned array and its contents are immutable, even if the values you originally set were mutable.
  • 返回的数组及其内容是不可变的,即使您最初设置的值是可变的。

But if you are 100% sure that "items" is not an empty NSArray, then you can downcast it to Array then .append()will work:

但是,如果您 100% 确定“ items”不是空的NSArray,那么您可以将其向下转换为 Array ,然后.append()将起作用:

var itemsArray = NSUserDefaults.standardUserDefaults().arrayForKey("items") as Array

If the return object from .arrayForKey()is nilor can't be cast to Array (e.g. it's objects can't be casted into Swift type), error will rise as it can't unwrap the optional.

如果返回的对象.arrayForKey()nil或不能转换为 Array(例如,它的对象不能转换为 Swift 类型),则错误将增加,因为它无法解开可选项。

回答by Daniel T.

Put this code in the sandbox and you will see that the value "hello" is appended properly. Figuring out what is different between my code and yours will be a great learning experience for you:

将此代码放入沙箱中,您将看到正确附加了值“hello”。弄清楚我的代码和你的代码之间有什么不同对你来说是一个很好的学习经验:

class ToDoListTableViewController: UITableViewController /*...*/ {
    var itemsArray: Array<AnyObject>!

    override func viewDidLoad() {
        super.viewDidLoad()
        if let savedItems = NSUserDefaults.standardUserDefaults().arrayForKey("items") {
            itemsArray = savedItems
        }
        else {
            itemsArray = []
        }
    }

    func testSave(item : NSString, date : NSString) {
        itemsArray.append(item)
    }
}

let list = ToDoListTableViewController()
list.viewDidLoad()
list.testSave("hello", date: "")
list.itemsArray

回答by jeet.chanchawat

If you are doing Mix and Match (gradually migrating from objc to swift)

如果你在做 Mix and Match(逐渐从 objc 迁移到 swift)

Then use

然后使用

nsMutableArray.addObject(nsMutableDictionary)

The replacement of appendyou are looking for is addObject

append你正在寻找的替代品是addObject

Hope this helps someone in future.

希望这对将来的人有所帮助。

回答by iQ.

It is not that your code is syntactically wrong, it is just that the method "arrayForKey" always gives back an immutable array which you can not modify.

并不是你的代码在语法上有问题,只是方法“arrayForKey”总是返回一个你不能修改的不可变数组。

You are trying to append, which modifies the length, hence it is not allowed.

您正在尝试追加,这会修改长度,因此是不允许的。

You can verify this in the documentation here is an extract for the return value:

您可以在文档中验证这一点,这里是返回值的摘录:

arrayForKey: Returns the array associated with the specified key.

...

Return Value The array associated with the specified key, or nil if the key does not exist or its value is not an NSArray object.

Special Considerations The returned array and its contents are immutable, even if the values you originally set were mutable.

arrayForKey:返回与指定键关联的数组。

...

返回值 与指定键关联的数组,如果键不存在或其值不是 NSArray 对象,则为 nil。

特殊注意事项 返回的数组及其内容是不可变的,即使您最初设置的值是可变的。

回答by Literphor

Even if you declare something as var it still needs a type to be anything other than AnyObject. Var I believe is just a keyword declaring that that the following identifier (the variable name) is to be inferred by it's assignment

即使您将某些内容声明为 var,它仍然需要一个类型为 AnyObject 以外的任何类型。我相信 Var 只是一个关键字,声明以下标识符(变量名)将通过它的赋值来推断

Since you want a Mutable Array try this

既然你想要一个可变数组试试这个

var itemsArray: NSMutableArray

or

或者

var itemsArray = NSMutableArray()

Edit: Don't know why I keep getting thumbs down. Now that that the question's been updated it seems that I was right. When you called

编辑:不知道为什么我一直在竖起大拇指。现在问题已经更新,看来我是对的。当你打电话

NSUserDefaults.standardUserDefaults().arrayForKey("items")

The return type is NSArray. The type inferred for the variable itemsArray is therefore NSArray, which is not mutable. Therefore wrap it in a mutable array

返回类型是 NSArray。因此,为变量 itemsArray 推断的类型是 NSArray,它是不可变的。因此将它包装在一个可变数组中

var itemsArray: NSMutableArray = NSMutableArray(array:NSUserDefaults.standardUserDefaults().arrayForKey("items"))