【问题标题】:Query data from Parse.com, iterate through, add certain parts to an NSObject, and add the object to an array of objects从 Parse.com 查询数据,遍历,将某些部分添加到 NSObject,并将对象添加到对象数组
【发布时间】:2014-08-06 21:16:32
【问题描述】:

我正在使用带有 Parse.com 的 SDK 的 iOS7 Xcode 5。在通过解析查询数据时,我试图为每个返回的对象构造一个人(NSObject)并创建一个 defaultPeople 的 NSArray。 这是 Person 的代码:

人.h

// 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

Person.m:

// Person.m

#import "Person.h"

@implementation Person

#pragma mark - Object Lifecycle

- (instancetype)initWithName:(NSString *)name
                       image:(UIImage *)image
                         age:(NSUInteger)age
                      gender:(NSString*)gender
                    location:(NSString *)location
                     tagline:(NSString*)tagline
                    objectId:(NSString *)objectId {
    self = [super init];
    if (self) {
        _name = name;
        _image = image;
        _age = age;
        _gender = gender;
        _location = location;
        _tagline = tagline;
        _objectId = objectId;
    }
    return self;
}

@end

现在这是我用来尝试在我的视图控制器 .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/NSUInteger 进行了 NSLogged,它总是返回正确的值。我的问题是从这些值创建一个新的 Person 对象,并在每次迭代后将其添加到 defaultPeople 数组中。此代码的结果是我的 defaultPeople 数组始终返回 (null)。请帮忙!!!谢谢:)

克莱顿

【问题讨论】:

  • 您在代码中的哪个位置将新的 Person 对象添加到数组中?
  • @Jacob - 将其编辑到我拥有它的位置,看看。非常感谢。

标签: for-loop ios7 nsarray parse-platform nsobject


【解决方案1】:

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

- (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 返回是让控制器知道是否在提示时切换视图控制器。如果按下开关控制器切换开关,它只会在 BOOL = 1 时切换,即该区域内有人。

感谢大家的帮助。认真的。

【讨论】:

  • 特别感谢@Jacob 支持我!
  • 如果我帮助了你,你至少会给我的答案投票吗?谢谢,很高兴你知道了。
【解决方案2】:

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

你可以用 [query findObjectsInBackground] 代替 NSArray *objects = [查询 findObjects]

【讨论】:

    【解决方案3】:

    你需要返回块内的人,否则它会在找到对象之前触发返回语句。它与块异步查找它们。

    另一种选择是摆脱阻塞并执行:

    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;
    

    【讨论】:

    • 我明白你在说什么。由于所有数据,我必须在一个块中(异步)执行此操作。我尝试将 return self.people 放在块内,但没有收到关于块和返回数组之间“不兼容指针类型”的错误
    • @rockandride 可能会将代码在另一个方法中对对象进行精细处理,然后在上面的 main 方法中返回对找到对象的方法的调用。
    • 也试过了 - 没有骰子。我什至在根视图上做了它并将它存储在一个单例中,希望当这个控制器弹出时数据会加载等等 - 仍然没有。
    • @rockandride 如果不使用块,所有对象都不会加载吗?
    • @rockandride 听起来不太对劲。你能解释更多吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多