0

I'm trying to loop through an array and add items to a new array. The addObject part exists inside a block. Something seems to be preventing any objects from being added to my new array. I'm wondering if the block is causing problems.

It goes like this:

-(void)queryForID
{
    NSLog(@"QUERY FOR ID");
    self.REST = [[AIREST alloc] init];
    [self.REST querySchema:@"business" searchString:@"object_id" fromArray:self.json.objects];
}

AIREST.h

#import <Foundation/Foundation.h>
#import "StackMob.h"

@interface AIREST : NSObject

-(void)querySchema:(NSString *)schema searchString:(NSString *)searchString fromArray:(NSArray *)searchArray;

@property (nonatomic, strong) NSMutableArray *queryResults;

@end

AIREST.m

-(void)querySchema:(NSString *)schema searchString:(NSString *)searchString fromArray:(NSArray *)searchArray
{
    self.queryResults = [[NSMutableArray alloc] init];

    for (int i = 0; i < [searchArray count]; i++)
    {
        MyObject *myObject = searchArray[i];
        SMQuery *newQuery = [[SMQuery alloc] initWithSchema:schema];
        [newQuery where:searchString isEqualTo:myObject.objectID];

        [[[SMClient defaultClient] dataStore] performQuery:newQuery onSuccess:^(NSArray *results) {
            // results contains an array of dictionary objects that match the query
            if ([results count] > 0)
            {
                [self.queryResults addObject:results];
                NSLog(@"QUERY: %@", self.queryResults);
            }
        } onFailure:^(NSError *error) {
            // Error
            NSLog(@"QUERY ERROR: %@", error);
        }];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"gotQueryResults" object:nil];
}

At the end of the loop, NSLog prints the contents of self.queryResults, except self.queryResults appears empty afterwards. Does this make any sense?

jmoneystl
  • 773
  • 1
  • 8
  • 23

3 Answers3

0

Your success and failure blocks are asynchronous. So postNotificationName: could be called before adding objects in self.queryResults. Try to use breakpoints to see how your code works.

Valentin Shamardin
  • 3,569
  • 4
  • 34
  • 51
0

instead of

@property (nonatomic, strong) NSMutableArray *queryResults;

use

@property (nonatomic, strong) __block NSMutableArray *queryResults;

hope this will work.

x4h1d
  • 6,042
  • 1
  • 31
  • 46
0

Your code is using several classes that you don't tell us about. AIREST, as mentioned by teh1, above.

You are also using the SMClient class, which looks like it's an open-source project on github. You should state that, tell us what it does and how it works.

Based on the method name of the method you're using, performQuery:onSuccess:onFailure:, it sounds to me like this method does an asynchronous network fetch of some kind.

If I'm right, it returns immediately, and then once the query is complete, the code in the "onSuccess" block is executed.

Your code is queuing up a whole batch of queries. When you leave the for loop none of your fetches have completed. In fact it's likely that the first byte of the first query request has even been sent over the network yet.

Thus, in the next statement you are posting a notification with the query results before the query has even executed.

Since you're starting multiple queries in a for loop you will have to get clever about figuring out when all of them are done.

One way to handle this would be to rewrite your code to have a query index instance variable, and write your code to send a query request with the onSuccess block parsing the results for that query and then incrementing the query index and starting a new query if there are more to be fetched.

Duncan C
  • 128,072
  • 22
  • 173
  • 272