gpt4 book ai didi

ios - Swift:尝试从数据源结构中检索数据

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:00:45 24 4
gpt4 key购买 nike

下面是我的代码:

class DataSource: NSObject {
var categories = [String]()
var items = [Item]()

private override init() {
super.init()
}

class var sharedDataSource: DataSource {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: DataSource!
}
dispatch_once(&Static.onceToken) {
let dataSource = DataSource()
Static.instance = dataSource

let urlPath = "myUrlPathString"
let endpoint = NSURL(string: urlPath)
let request = NSMutableURLRequest(URL: endpoint!)

NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: { (data, response, error) in
let json = JSON(data: data!)
print(json)
for obj in json.arrayValue {
let item: Item = Item()
item.itemID = obj["item"].stringValue
item.price = obj["price"].floatValue
item.title = obj["title"].stringValue
item.category = obj["category"].stringValue
item.available = obj["available"].boolValue
item.image = obj["image"].stringValue
print(item.title)
dataSource.items.append(item)
print(dataSource.items)
print("STOP")
}
}).resume()
}
return Static.instance
}
}

我试图通过将其结果分配给 Item 数组来在 UICollectionView 中使用此数据源的结果。我成功地获取了我的 NSURLSession 中的数据,并且正在填充其本地列表“items”。

在我的 UICollectionView 中,在我的 viewDidLoad 中,我按如下方式分配局部变量:

let dataSource = DataSource()
items = dataSource.sharedInstance.items

在 viewDidLoad 中打印值总是会产生一个没有值的空数组,但我知道在 NURLSession 完成时值已经存在。我不确定如何为此编写完成处理程序。这是我第一次使用作为结构的 sharedDataSource 做这种事情。

有什么想法吗?

谢谢,

肖恩

最佳答案

如果您在 viewDidLoad 中执行此操作,则可能在您尝试获取项目数组时 NSURL session 尚未完成。收到数据后,在您的数据源类中发送通知,然后设置项目。

例如

 NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: { (data, response, error) in
let json = JSON(data: data!)
print(json)
for obj in json.arrayValue {
let item: Item = Item()
item.itemID = obj["item"].stringValue
item.price = obj["price"].floatValue
item.title = obj["title"].stringValue
item.category = obj["category"].stringValue
item.available = obj["available"].boolValue
item.image = obj["image"].stringValue
print(item.title)
dataSource.items.append(item)
print(dataSource.items)
print("STOP")
}
NSNotificationCenter.defaultCenter().postNotificationName("dataRecievedNotification", object: nil)

}).resume()

但是您还需要能够在带有 collectionView 的 ViewController 中接收此通知。所以在viewDidLoad中添加

NSNotificationCenter.defaultCenter().addObserver(self, selector: "dataRecieved", name: "dataRecievedNotification", object: nil)

然后在同一个ViewController中添加一个函数:

func dataRecieved() {
print("data received")
items = dataSource.sharedInstance.items
collectionView.reloadData()
}

其中dataSource是viewDidLoad上面声明的变量:

let dataSource = DataSource()

不要忘记,如果你正在使用观察者,你需要在类从内存中移除时移除它们,因此在 ViewController 中添加这个 deinit 函数:

deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}

编辑:我认为您的单例模式可以使用现代 swift 进行简化。您不必再使用 struct 或 dispatch_once ,只需声明一个 static let shared 实例即可为您处理所有这些。考虑到这一点,我尝试简化您的数据源类:

class DataSource {

static let sharedInstance = DataSource()

var items = [Item]()

private init() {}

func retrieveItems() {

let urlPath = "myUrlPathString"
let endpoint = NSURL(string: urlPath)
let request = NSMutableURLRequest(URL: endpoint!)

NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: { (data, response, error) in

let json = JSON(data: data!)
print(json)

for obj in json.arrayValue {
let item: Item = Item()
item.itemID = obj["item"].stringValue
item.price = obj["price"].floatValue
item.title = obj["title"].stringValue
item.category = obj["category"].stringValue
item.available = obj["available"].boolValue
item.image = obj["image"].stringValue
print(item.title)
items.append(item)
print(items)
print("STOP")
}

NSNotificationCenter.defaultCenter().postNotificationName("dataRecievedNotification", object: nil)

}).resume()

}

}

您在 viewDidLoad 中添加以下逻辑:

if DataSource.sharedInstance.items.count == 0 {
DataSource.sharedInstance.retrieveItems()
}

然后将dataRecieved改成

func dataRecieved() {
print("data received")
items = DataSource.sharedInstance.items //Notice the capital
collectionView.reloadData()
}

并删除 viewDidLoad 上面的 var dataSource = DataSource() 声明

关于ios - Swift:尝试从数据源结构中检索数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37013739/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com