在Swift 2.0中填充列表并显示结果

时间:2016-06-15 04:01:42

标签: ios list swift2

过去三周我一直在学习iOS开发,目前我正在关注Udemy的课程。

但是,我正在按照其中一个讲座来构建Instagram克隆。

教师使用三个数组,如下所示:

var usernames = [""] // Stores all usernames
var userIds = [""] // Stores all Id's of the given usernames
var isFollowing = [false] // Stores where or not you're following that user

对于我试图跟踪userId使用两个数组的用户名是什么基本上是一个等待发生的事故,所以我决定出发并找到一个更可行的方法。我回到了我的.Net日,并决定创建一个列表,所以我去创建了一个类如下:

class Users{   
  var Username : NSString = ""
  var UserId : NSString = ""
  var Following : Bool = false
}

现在我的ViewController内部我调用了Parse,它返回了一个用户列表,我基本上试图遍历响应,然后将它们添加到列表类中,如下所示:

  var t = [Users]() // After googling the web, this seems to be the syntax for a list declaration ? 
  let u = Users()

  for object in users{

     if let o = object as? PFUser {

        u.Username = o.username!
        u.UserId = o.objectId!
        u.Following = o.IsFollowing!

       self.t.append(u)

       }

  }

 print(self.t)

现在,当我将其打印到控制台时,我看到以下内容:

ParseStarterProject_Swift.Users

由于我目前有一个用户,但是当我尝试循环播放T并在控制台中显示用户名时,它不会显示任何内容。

for x in t {

   print(x.Username)

}

2 个答案:

答案 0 :(得分:2)

你的基本直觉是正确的,最好有一个自定义对象数组,而不是多个数组。

关于使其更加Swifty,请考虑您的Users类型。您可能需要以下内容:

struct User {   
    let username: String
    let userId: String
    let following: Bool
}

注意,

  • 属性名称应以小写字母开头;
  • Users应该被称为User,因为它代表一个用户;
  • 我们通常不会将值初始化为默认值,而是在初始化程序中指定它们;
  • 我们可能使用String而不是NSString;
  • 如果属性无法更改,则使用let,而不是var;
  • 属性以小写字母开头;

然后你可以做类似的事情:

var t = [User]()

for object in users {
    if let o = object as? PFUser {
        t.append(User(username: o.username!, userId: o.objectId!, following: o.IsFollowing!)
    }
}

print(t)

显然,对于所有!强制解包运算符,您需要确信这些字段已填充所有这些属性。

使用struct很好,因为(a)它是一个值类型; (b)你免费获得初始化程序; (c)你可以打印它们。如果您真的希望User成为引用类型(class),您可以执行以下操作:

class User {
    let username: String
    let userId: String
    let following: Bool

    init(username: String, userId: String, following: Bool) {
        self.username = username
        self.userId = userId
        self.following = following
    }
}

如果你想只能print他们,你可以将其定义为符合CustomStringConvertible

extension User: CustomStringConvertible {
    var description: String { return "<User; username = \(username); userId = \(userId); following = \(following)>" }
}

使用该类,您可以随意更改description计算属性,以便以您想要的任何格式显示它,但它说明了这一想法。

答案 1 :(得分:1)

考虑到跟踪userId使用两个阵列的用户名是危险的,你是正确的,你的方法是正确的。

首先,我想建议您使用正确的命名约定:

  1. 课程应该是单一的(除非在非常具体的情况下)。
  2. 变量/属性名称应以小写开头。
  3. 这意味着您的用户类应如下所示:

    class User {   
      var username : NSString = ""
      var userId : NSString = ""
      var following : Bool = false
    }
    

    我将保留您现有的命名用于下一部分。代码的主要问题是变量“u”是一个只创建一次然后修改它的对象。您应该为每个用户创建一个新的“用户”对象,而不是修改原始对象。如果不这样做,您将只有多个具有相同用户的阵列。这就是您的代码现在的样子:

      var t = [Users]()
    
      for object in users {
    
         if let o = object as? PFUser {
    
            let u = Users()
    
            u.Username = o.username!
            u.UserId = o.objectId!
            u.Following = o.IsFollowing!
    
            self.t.append(u)
    
         }
    
      }
    
     print(self.t)
    

    接下来,您提到当您打印到控制台时,您会看到文本:ParseStarterProject_Swift.Users,这是因为Swift不会自动打印包含对象内容的漂亮文本。为了打印更详细的内容,您的“用户”对象需要实现CustomStringConvertible。你可以在这里看到更详细的答案:how-can-i-change-the-textual-representation-displayed-for-a-type-in-swif

    最后,你提到当你循环“t”并在控制台中显示用户名时它不会显示任何内容。这是由两件事之一引起的:

    1. 因为没有用户从parse返回,所以“t”数组实际上是空的。尝试print(t.count)查看数组中有多少个对象。
    2. 因为您的“Users”对象声明了一个空字符串“”作为默认用户名,并且在从解析中获取数据时未正确设置用户名。这意味着它实际上是在打印一些东西,只是它是一个空字符串。尝试定义一个不同的默认值,如var username : NSString = "Undefined",看它是否打印出来。
    3. 祝好运快速学习!