在Swift中,如何停止所有进程,直到从UICOLLECTIONVIEW中的parse.com检索到数据为止
在CollectionView中,我显示来自parse.com的数据。已成功检索。但无法在单元格中显示。我在阵列出站时收到错误。我发现了错误,parse是异步运行的。但是,在解析结束之前,将加载集合视图。因此,我无法在单元格中显示值。这是一个错误。如何停止所有进程,直到完全加载解析?请引导我。 我的代码如下:在Swift中,如何停止所有进程,直到从UICOLLECTIONVIEW中的parse.com检索到数据为止,swift,parse-platform,uicollectionview,grand-central-dispatch,Swift,Parse Platform,Uicollectionview,Grand Central Dispatch,在CollectionView中,我显示来自parse.com的数据。已成功检索。但无法在单元格中显示。我在阵列出站时收到错误。我发现了错误,parse是异步运行的。但是,在解析结束之前,将加载集合视图。因此,我无法在单元格中显示值。这是一个错误。如何停止所有进程,直到完全加载解析?请引导我。 我的代码如下: //VIEWCONTROLLER having collectionView var myList : NSArray = NSArray() let obj_par = parse_
//VIEWCONTROLLER having collectionView
var myList : NSArray = NSArray()
let obj_par = parse_retrive()
obj_par.parse_DB() //DATAS GOING TO RETRIVE FROM PARSE
story_collection_view.reloadData() //RELOADING COLLECTIONVIEW
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
println("fifth")
if(collectionView == date_collection_view)
{
:
:
return cell
}
else
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("story_read", forIndexPath: indexPath) as story_reading_cell
cell.story_title.text = myList.objectAtIndex(indexPath.row) as? String //ERROR: ARRAY OUTBOUND OF INDEX
return cell
}
}
//解析检索类
func parse_DB() {
println("SECOND 10")
par_query.findObjectsInBackgroundWithBlock({(NSArray objects, NSError error) in
if (error != nil) {
NSLog("error " + error.localizedDescription)
}
else {
println("SECOND 13")
let sql_store_obj1 = sql_to_store() //THIRD CLASS
self.parse_obj_arr = NSArray(array: objects)
var j : Int = self.parse_obj_arr.count
for (var i : Int = 0; i < j; i++) {
self.par_object = self.parse_obj_arr.objectAtIndex(i) as PFObject
self.sto = self.par_object["story_title"] as String //STORY TITLE FROM PARSE
self.sto_con = self.par_object["story_content"] as String //STORY CONTENT FROM PARSE
self.sto_tit.append(self.sto) //STORING IN ARRAY VAR
self.sto_cont.append(self.sto_con) //STORING IN ARRAY VAR
} //FOR ENDING
sql_store_obj1.sto_title_arr = self.sto_tit
sql_store_obj1.sto_content_arr = self.sto_cont
sql_store_obj1.parse_to_sql()
}//ELSE ENDING
}) //PARSE QUERY ENDING
println("SECOND")
}
注意:所有代码都是Objective-C,但是这个特定代码的翻译应该很简单。如果有人想编辑我的帖子以包含Swift代码,请随意,但请将Objective-C留在帖子中
我为UICollectionView或UITableView所做的是创建一个属性,通常称为isLoading,如下所示:
@property (assign, nonatomic) BOOL isLoading;
- (void)viewDidLoad {
[super viewDidLoad];
// This could also be done in viewWillAppear/viewDidAppear
// based on your needs/desires
self.isLoading = NO;
[self loadData];
}
- (void)loadData {
if (self.isLoading == YES) {
// Just in case a "loadData" call is made while one is pending...
return;
}
// Prevent this method from firing again until
// data loading is done; prevent UICollectionView
// from attempting to display missing data
self.isLoading = YES;
// Do whatever you need to do...
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.isLoading == YES) {
// You might want to return 0 or 1,
// depending on whether you have a "loading"
// placeholder cell. Assume you do:
return 1;
} else {
// Return whatever is the correct number here
}
}
@property (assign, nonatomic) BOOL data1Loaded;
@property (assign, nonatomic) BOOL data2Loaded;
@property (assign, nonatomic) BOOL data3Loaded;
@property (assign, nonatomic) BOOL data4Loaded;
- (void)loadData {
if (self.isLoading == YES) {
return;
}
self.isLoading = YES;
self.data1Loaded = NO;
self.data2Loaded = NO;
self.data3Loaded = NO;
self.data4Loaded = NO;
// Call each of the separate data loading methods...
[self loadData1];
[self loadData2];
[self loadData3];
[self loadData4];
// Notice that I don't do any reloadData calls here...
}
- (void)loadData1 {
PFQuery *query = // Some query creation...
[query findObjectsInBackgroundWithBlock:
^(NSArray *objects, NSError *error) {
if (error != nil) {
// Handle "got error"
} else {
// Handle "got good data"
}
// Either way, #1 is done, so:
self.data1Loaded = YES;
// This pattern checks for completion and
// runs the completion code only when all
// 4 (in this case) items/queries have returned
[self checkIfDone];
}
];
}
- (void)checkIfDone {
if (self.data1Loaded == YES &&
self.data2Loaded == YES &&
self.data3Loaded == YES &&
self.data4Loaded == YES)
{
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
}
我通常会这样初始化它:
@property (assign, nonatomic) BOOL isLoading;
- (void)viewDidLoad {
[super viewDidLoad];
// This could also be done in viewWillAppear/viewDidAppear
// based on your needs/desires
self.isLoading = NO;
[self loadData];
}
- (void)loadData {
if (self.isLoading == YES) {
// Just in case a "loadData" call is made while one is pending...
return;
}
// Prevent this method from firing again until
// data loading is done; prevent UICollectionView
// from attempting to display missing data
self.isLoading = YES;
// Do whatever you need to do...
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.isLoading == YES) {
// You might want to return 0 or 1,
// depending on whether you have a "loading"
// placeholder cell. Assume you do:
return 1;
} else {
// Return whatever is the correct number here
}
}
@property (assign, nonatomic) BOOL data1Loaded;
@property (assign, nonatomic) BOOL data2Loaded;
@property (assign, nonatomic) BOOL data3Loaded;
@property (assign, nonatomic) BOOL data4Loaded;
- (void)loadData {
if (self.isLoading == YES) {
return;
}
self.isLoading = YES;
self.data1Loaded = NO;
self.data2Loaded = NO;
self.data3Loaded = NO;
self.data4Loaded = NO;
// Call each of the separate data loading methods...
[self loadData1];
[self loadData2];
[self loadData3];
[self loadData4];
// Notice that I don't do any reloadData calls here...
}
- (void)loadData1 {
PFQuery *query = // Some query creation...
[query findObjectsInBackgroundWithBlock:
^(NSArray *objects, NSError *error) {
if (error != nil) {
// Handle "got error"
} else {
// Handle "got good data"
}
// Either way, #1 is done, so:
self.data1Loaded = YES;
// This pattern checks for completion and
// runs the completion code only when all
// 4 (in this case) items/queries have returned
[self checkIfDone];
}
];
}
- (void)checkIfDone {
if (self.data1Loaded == YES &&
self.data2Loaded == YES &&
self.data3Loaded == YES &&
self.data4Loaded == YES)
{
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
}
现在,真正的秘密当然是,您必须在UICollectionViewDataSource方法中实现逻辑,以便根据self.isLoading有条件地显示数据,如下所示:
@property (assign, nonatomic) BOOL isLoading;
- (void)viewDidLoad {
[super viewDidLoad];
// This could also be done in viewWillAppear/viewDidAppear
// based on your needs/desires
self.isLoading = NO;
[self loadData];
}
- (void)loadData {
if (self.isLoading == YES) {
// Just in case a "loadData" call is made while one is pending...
return;
}
// Prevent this method from firing again until
// data loading is done; prevent UICollectionView
// from attempting to display missing data
self.isLoading = YES;
// Do whatever you need to do...
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.isLoading == YES) {
// You might want to return 0 or 1,
// depending on whether you have a "loading"
// placeholder cell. Assume you do:
return 1;
} else {
// Return whatever is the correct number here
}
}
@property (assign, nonatomic) BOOL data1Loaded;
@property (assign, nonatomic) BOOL data2Loaded;
@property (assign, nonatomic) BOOL data3Loaded;
@property (assign, nonatomic) BOOL data4Loaded;
- (void)loadData {
if (self.isLoading == YES) {
return;
}
self.isLoading = YES;
self.data1Loaded = NO;
self.data2Loaded = NO;
self.data3Loaded = NO;
self.data4Loaded = NO;
// Call each of the separate data loading methods...
[self loadData1];
[self loadData2];
[self loadData3];
[self loadData4];
// Notice that I don't do any reloadData calls here...
}
- (void)loadData1 {
PFQuery *query = // Some query creation...
[query findObjectsInBackgroundWithBlock:
^(NSArray *objects, NSError *error) {
if (error != nil) {
// Handle "got error"
} else {
// Handle "got good data"
}
// Either way, #1 is done, so:
self.data1Loaded = YES;
// This pattern checks for completion and
// runs the completion code only when all
// 4 (in this case) items/queries have returned
[self checkIfDone];
}
];
}
- (void)checkIfDone {
if (self.data1Loaded == YES &&
self.data2Loaded == YES &&
self.data3Loaded == YES &&
self.data4Loaded == YES)
{
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
}
通常,这就是让屏幕延迟加载UICollectionView直到正确返回解析查询所需的全部内容
当我有多个并发运行的查询时,所有这些都应该在我考虑数据加载完成之前返回,然后我为它们中的每一个创建一个布尔属性,适当地设置标志,并且通过CIFIFON方法漏掉所有的查询返回。大概是这样的:
@property (assign, nonatomic) BOOL isLoading;
- (void)viewDidLoad {
[super viewDidLoad];
// This could also be done in viewWillAppear/viewDidAppear
// based on your needs/desires
self.isLoading = NO;
[self loadData];
}
- (void)loadData {
if (self.isLoading == YES) {
// Just in case a "loadData" call is made while one is pending...
return;
}
// Prevent this method from firing again until
// data loading is done; prevent UICollectionView
// from attempting to display missing data
self.isLoading = YES;
// Do whatever you need to do...
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.isLoading == YES) {
// You might want to return 0 or 1,
// depending on whether you have a "loading"
// placeholder cell. Assume you do:
return 1;
} else {
// Return whatever is the correct number here
}
}
@property (assign, nonatomic) BOOL data1Loaded;
@property (assign, nonatomic) BOOL data2Loaded;
@property (assign, nonatomic) BOOL data3Loaded;
@property (assign, nonatomic) BOOL data4Loaded;
- (void)loadData {
if (self.isLoading == YES) {
return;
}
self.isLoading = YES;
self.data1Loaded = NO;
self.data2Loaded = NO;
self.data3Loaded = NO;
self.data4Loaded = NO;
// Call each of the separate data loading methods...
[self loadData1];
[self loadData2];
[self loadData3];
[self loadData4];
// Notice that I don't do any reloadData calls here...
}
- (void)loadData1 {
PFQuery *query = // Some query creation...
[query findObjectsInBackgroundWithBlock:
^(NSArray *objects, NSError *error) {
if (error != nil) {
// Handle "got error"
} else {
// Handle "got good data"
}
// Either way, #1 is done, so:
self.data1Loaded = YES;
// This pattern checks for completion and
// runs the completion code only when all
// 4 (in this case) items/queries have returned
[self checkIfDone];
}
];
}
- (void)checkIfDone {
if (self.data1Loaded == YES &&
self.data2Loaded == YES &&
self.data3Loaded == YES &&
self.data4Loaded == YES)
{
// Clean up and prepare for UICollectionView
self.isLoading = NO;
[self.collectionView reloadData];
}
}
警告:这假设对loadData的任何后续调用都将在后台进行,并且对[collectionView reloadData]的任何后续调用都将仅在查询调用结束时进行。如果同时还有其他任何东西可能调用reloadData,则需要更高级的逻辑来确保正确加载正确的数据
旁注:在进行类似操作时,不要忘记向用户显示工作正在进行的指示。我喜欢使用开源的MBProgressHUD。有空。我发现它对于你所说的做什么都是无价的