For loop 从Parse.com查询数据,遍历,将某些部分添加到NSObject,并将该对象添加到对象数组中

For loop 从Parse.com查询数据,遍历,将某些部分添加到NSObject,并将该对象添加到对象数组中,for-loop,ios7,nsarray,parse-platform,nsobject,For Loop,Ios7,Nsarray,Parse Platform,Nsobject,我正在Parse.com的SDK中使用ios7xcode 5。在通过parse查询数据时,我试图为每个返回的对象构造一个Person(NSObject),并创建一个defaultPeople的NSArray。 以下是该人员的代码: 人 // Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic, strong) NSString *name; @p

我正在Parse.com的SDK中使用ios7xcode 5。在通过parse查询数据时,我试图为每个返回的对象构造一个Person(NSObject),并创建一个defaultPeople的NSArray。 以下是该人员的代码:

// Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, strong) NSString *gender;
@property (nonatomic, strong) NSString *location;
@property (nonatomic, strong) NSString *tagline;
@property (nonatomic, strong) NSString *objectId;

- (instancetype)initWithName:(NSString *)name
                       image:(UIImage *)image
                         age:(NSUInteger)age
                      gender:(NSString*)gender
                    location:(NSString*)location
                     tagline:(NSString*)tagline
                    objectId:(NSString*)objectId;

@end
下面是我用来尝试在我的view controller.m文件中创建数组的代码:

- (NSArray *)defaultPeople {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSLog(@"Current City for Querying: %@", [defaults objectForKey:@"CurrentCity"]);
    if ([defaults objectForKey:@"CurrentCity"]) {
    PFQuery *query = [PFQuery queryWithClassName:@"_User"];
        [query whereKey:@"CurrentCity" equalTo:[defaults objectForKey:@"CurrentCity"]];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                if (!error) {
                    // The find succeeded.
                    NSLog(@"Successfully retrieved %d scores.", objects.count);
                    // Do something with the found objects
                    for (PFObject *object in objects) {
                        NSString *userID = object.objectId;
                        NSString *first = [object objectForKey:@"FirstName"];
                        NSString *city = [object objectForKey:@"CurrentCity"];
                        NSUInteger age = (int)[object objectForKey:@"Age"];
                        NSString *gender = [object objectForKey:@"Gender"];
                        NSString *tagline = [object objectForKey:@"Tagline"];

                        Person *p = [[Person alloc] 
                                            initWithName:first
                                                   image:[UIImage imageWithData:
                                                         [NSData dataWithContentsOfURL:                                                                                            
                                                         [NSURL URLWithString:
                                                         [object objectForKey:@"PictureURL"]]]]
                                                 age:age
                                              gender:gender
                                            location:city
                                             tagline:tagline
                                            objectId:userID];
                [self.people addObject:p]
                }
        } else {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
            }
        }];
    }
    return self.people; //people was defined in the interface as: 
                        //@property (nonatomic, strong) NSMutableArray *people;
}
我知道查询很好,因为我在for循环中记录了每个NSString/nsInteger,它总是返回正确的值。我的问题是从这些值创建一个新的Person对象,并在每次迭代后将其添加到defaultPeople数组中。此代码的结果是我的defaultPeople数组始终返回(null)。请帮忙!!!谢谢:)


Clayton

您需要返回块中的人员,否则它将在完成查找对象之前命中return语句。它与块异步地查找它们

另一种选择是清除该块并执行以下操作:

NSArray *array = [query findObjects];

for (PFObject *object in array) {
                        NSString *userID = object.objectId;
                        NSString *first = [object objectForKey:@"FirstName"];
                        NSString *city = [object objectForKey:@"CurrentCity"];
                        NSUInteger age = (int)[object objectForKey:@"Age"];
                        NSString *gender = [object objectForKey:@"Gender"];
                        NSString *tagline = [object objectForKey:@"Tagline"];

                        Person *p = [[Person alloc] 
                                            initWithName:first
                                                   image:[UIImage imageWithData:
                                                         [NSData dataWithContentsOfURL:                                                                                            
                                                         [NSURL URLWithString:
                                                         [object objectForKey:@"PictureURL"]]]]
                                                 age:age
                                              gender:gender
                                            location:city
                                             tagline:tagline
                                            objectId:userID];
                [self.people addObject:p];

}

return self.people;

[self.people addObject:p]发生在后台线程中,因此“return self.people”发生在self.people更新之前。这就是为什么它总是返回零

您可以执行以下操作,而不是[query findObjectsInBackground]
NSArray*objects=[query findObjects]

好了,伙计们,我终于想出了在一个实际工作的块中如何做到这一点:

- (void)queryForAllPostsNearLocation:(CLLocation *)currentLocation withNearbyDistance:(CLLocationAccuracy)nearbyDistance {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:1 forKey:@"Users"];
    PFQuery *query = [PFQuery queryWithClassName:@"_User"];
    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    if (query.countObjects == 0) {
        query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    }

    // Create a PFGeoPoint using the current location (to use in our query)
    PFGeoPoint *userLocation =
    [PFGeoPoint geoPointWithLatitude:[Global shared].LastLocation.latitude longitude:[Global shared].LastLocation.longitude];

    // Create a PFQuery asking for all wall posts 1km of the user
    [query whereKey:@"CurrentCityCoordinates" nearGeoPoint:userLocation withinKilometers:10];
    // Include the associated PFUser objects in the returned data
    [query includeKey:@"objectId"];
    //Run the query in background with completion block
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (error) { // The query failed
        NSLog(@"Error in geo query!");
    } else { // The query is successful
        defaultPeople = [[NSMutableArray alloc] init];
        // 1. Find new posts (those that we did not already have)
        // In this array we'll store the posts returned by the query
        NSMutableArray *people = [[NSMutableArray alloc] initWithCapacity:100];
        // Loop through all returned PFObjects
        for (PFObject *object in objects) {
            // Create an object of type Person with the PFObject
            Person *p = [[Person alloc] init];
            NSString *userID = object.objectId;
            p.objectId = userID;

            NSString *first = [object objectForKey:@"FirstName"];
            p.name = first;

            NSString *city = [object objectForKey:@"CurrentCity"];
            p.location = city;

            NSString *age = [object objectForKey:@"Age"];
            p.age = age;

            NSString *gender = [object objectForKey:@"Gender"];
            p.gender = gender;

            NSString *tagline = [object objectForKey:@"Tagline"];
            p.tagline = tagline;

            UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",[object objectForKey:@"PictureURL"]]]]];
            p.image = img;
            if (![p.objectId isEqualToString:myID] && ![p.gender isEqualToString:myGender] && ![people containsObject:p]) {
                [people addObject:p];
                NSLog(@"Person: %@",p);
            }
        }
        [defaultPeople addObjectsFromArray:people];
        [[Global shared] setDefaultPeople:defaultPeople];
        NSLog(@"Default People: %@",[Global shared].defaultPeople);
        NSLog(@"Success. Retrieved %lu objects.", (unsigned long)[Global shared].defaultPeople.count);
        if (defaultPeople.count == 0) {
            [defaults setBool:0 forKey:@"Users"];
        } else {
            [defaults setBool:1 forKey:@"Users"];
            }
        }
    }];
}
底部的布尔返回用于在提示时让控制器知道是否切换视图控制器。如果按下开关控制器开关,则仅当BOOL=1时才会切换,即该区域有人


谢谢你们的帮助。说真的。

在你的代码中,你在哪里将新的Person对象添加到数组中?@Jacob-将它编辑到我拥有它的地方,看一看。非常感谢。我明白你的意思。由于所有的数据,我必须在一个块中(异步)完成它。我尝试将return self.people放入块中,但没有得到关于“不兼容指针类型”的错误在阻塞和返回之间array@rockandride也许把代码放在另一个方法中,然后在上面的主方法中返回对找到对象的方法的调用。已经尝试过了-没有骰子。我甚至在根视图上这样做,并将其存储在一个单例中,希望当这个控制器弹出时,数据会加载,等等-仍然没有任何内容。@rockandride如果不使用块,所有对象都不会加载吗?@rockandride听起来不太对。你能再解释一下吗?特别感谢你跟我说了这件事!如果我帮了你,你会投票支持我的答案吗?谢谢,很高兴你明白了。
- (void)queryForAllPostsNearLocation:(CLLocation *)currentLocation withNearbyDistance:(CLLocationAccuracy)nearbyDistance {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:1 forKey:@"Users"];
    PFQuery *query = [PFQuery queryWithClassName:@"_User"];
    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    if (query.countObjects == 0) {
        query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    }

    // Create a PFGeoPoint using the current location (to use in our query)
    PFGeoPoint *userLocation =
    [PFGeoPoint geoPointWithLatitude:[Global shared].LastLocation.latitude longitude:[Global shared].LastLocation.longitude];

    // Create a PFQuery asking for all wall posts 1km of the user
    [query whereKey:@"CurrentCityCoordinates" nearGeoPoint:userLocation withinKilometers:10];
    // Include the associated PFUser objects in the returned data
    [query includeKey:@"objectId"];
    //Run the query in background with completion block
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (error) { // The query failed
        NSLog(@"Error in geo query!");
    } else { // The query is successful
        defaultPeople = [[NSMutableArray alloc] init];
        // 1. Find new posts (those that we did not already have)
        // In this array we'll store the posts returned by the query
        NSMutableArray *people = [[NSMutableArray alloc] initWithCapacity:100];
        // Loop through all returned PFObjects
        for (PFObject *object in objects) {
            // Create an object of type Person with the PFObject
            Person *p = [[Person alloc] init];
            NSString *userID = object.objectId;
            p.objectId = userID;

            NSString *first = [object objectForKey:@"FirstName"];
            p.name = first;

            NSString *city = [object objectForKey:@"CurrentCity"];
            p.location = city;

            NSString *age = [object objectForKey:@"Age"];
            p.age = age;

            NSString *gender = [object objectForKey:@"Gender"];
            p.gender = gender;

            NSString *tagline = [object objectForKey:@"Tagline"];
            p.tagline = tagline;

            UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",[object objectForKey:@"PictureURL"]]]]];
            p.image = img;
            if (![p.objectId isEqualToString:myID] && ![p.gender isEqualToString:myGender] && ![people containsObject:p]) {
                [people addObject:p];
                NSLog(@"Person: %@",p);
            }
        }
        [defaultPeople addObjectsFromArray:people];
        [[Global shared] setDefaultPeople:defaultPeople];
        NSLog(@"Default People: %@",[Global shared].defaultPeople);
        NSLog(@"Success. Retrieved %lu objects.", (unsigned long)[Global shared].defaultPeople.count);
        if (defaultPeople.count == 0) {
            [defaults setBool:0 forKey:@"Users"];
        } else {
            [defaults setBool:1 forKey:@"Users"];
            }
        }
    }];
}