在Swift中,如何停止所有进程,直到从UICOLLECTIONVIEW中的parse.com检索到数据为止

在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_

在CollectionView中,我显示来自parse.com的数据。已成功检索。但无法在单元格中显示。我在阵列出站时收到错误。我发现了错误,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。有空。我发现它对于你所说的做什么都是无价的