質問

I'm using JSONModel to retrieve data from a simple webservice. I need to get the values of key @"message" into a mutable array.

 - (void)viewDidLoad
{
     [super viewDidLoad];
     self.delegate = self;
     self.dataSource = self;

     NSString *conversationid = @"xx";
     NSString *callURL = [NSString stringWithFormat:@"http://mydomain.com/inbox_messages.php?conversation=%@", conversationid];

     _feed = [[MessageFeed alloc] initFromURLWithString:callURL
            completion:^(JSONModel *model, JSONModelError *err)
     {
          self.messages = [[NSMutableArray alloc]initWithObjects:[_feed.messagesinconversation valueForKey:@"message"], nil];
          NSLog(@"messages %@", self.messages);
     }];
     NSLog(@"test %@", self.messages);
}

The problem I'm experiencing is that while: NSLog(@"messages %@", self.messages); returns all the right data, NSLog(@"test %@", self.messages); returns (null).

The variable is declared in .h of my class as: @property (strong, nonatomic) NSMutableArray *messages;

This is probably a noob question but I'm a beginner and if somebody could give me a pointer in the right direction, I would be very happy.

役に立ちましたか?

解決

Your NSLog for self.messages is outside of the completion block. The completion block is called after the data is loaded. The log is called immediately after creating the MessageFeed request. So, of course, the object self.messages is null because the request has not completed.

The solution to this would be to either handle all of your parsing within the completion block, or call another class method to parse the received data.

他のヒント

Your completion handler is being called after your NSLog("test %@", self.messages); is.

Blocks usually happen concurrently and when a certain event has occurred like the completion handler here or sometimes an error handler. By looking at your code you're probably getting something like:

test nil messages

So your MessageFeed object is being run but it continues through your code and runs the NSLog outside of the completion handler scope first. When your JSON object has downloaded, which happens after, and parses it then runs the completion handler.

 - (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
self.dataSource = self;

NSString *conversationid = @"xx";
NSString *callURL = [NSString stringWithFormat:@"http://mydomain.com/inbox_messages.php?conversation=%@", conversationid];

_feed = [[MessageFeed alloc] initFromURLWithString:callURL //this method takes some time to complete and is handled on a different thread.
            completion:^(JSONModel *model, JSONModelError *err)
         {
             self.messages = [[NSMutableArray alloc]initWithObjects:[_feed.messagesinconversation valueForKey:@"message"], nil];
             NSLog(@"messages %@", self.messages); // this is called last in your code and your messages has been has been set as an iVar.
         }];
  NSLog(@"test %@", self.messages); // this logging is called immediately after initFromURLWithString is passed thus it will return nothing
 }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top