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
}