Objective-C возвращает данные из асинхронного NSURLConnection - заполнение класса модели данными - PullRequest
0 голосов
/ 11 октября 2011

То, чего я хочу достичь, это класс для разбора JSON.Я знаю, как анализировать JSON, и у меня nsurlconnection работает через делегат.Проблема в том, что я хочу создать метод в этом классе, который будет возвращать NSArray этих проанализированных элементов из json.Что у меня сейчас:

@interface JSONParser : NSObject {
    NSMutableData *responseData;
    NSString *url;

    SBJsonParser *parser;
}

@property (nonatomic, retain) NSString *url;

@end

и

@implementation JSONParser

@synthesize url;

- (id)init
{
    self = [super init];
    if (self) {
        responseData = [[NSMutableData data] retain];
        parser = [[SBJsonParser alloc] init];
        url = [[NSString alloc] init];
    }

    return self;
}

- (NSArray *) parse {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[self url]]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [request release];
    return ?;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];

        NSMutableArray *results = [[NSMutableArray alloc] init];
        //some parsing, filling the NSMutableArray
}

Я хочу добиться того, чтобы метод синтаксического анализа как-то возвращал массив, сгенерированный через nsurlconnection.Когда он будет сгенерирован, я хочу вернуть его в созданную мной модель синглтона.Или есть другой / лучший подход к этому?Я в основном хочу заполнить мою модель данными из JSON.Но проблема в том, что у меня будет несколько разных моделей, и я не могу просто указать одну для сохранения в методе connectionDidFinishLoading.Спасибо за помощь.

1 Ответ

1 голос
/ 11 октября 2011

Существует несколько вариантов анализа данных JSON. SBJSON был упомянут. JSONKit - еще один очень быстрый вариант. На самом деле это не сложнее, чем ходить по экземплярам NSArray и NSDictionary, возвращаемым анализатором.

EDIT: Я вижу; вам интересно, как передать результаты асинхронного процесса обратно любому объекту, создавшему этот процесс. Почему бы не использовать блоки для этого?

Определите блок завершения для этого:

typedef void(^myJSONReturnBlock)(NSArray *jsonObjs);

и ivar для него в вашем классе синтаксического анализатора:

@interface MYParserClass : NSObject
{
    myJSONReturnBlock _completionHandler;
}

Тогда ваш parse метод будет выглядеть примерно так:

- (void)parseWithCompletionHandler:(myJSONReturnBlock)aHandler;
{
    _completionHandler = Block_copy(aHandler);
    //  set up your asynchronous NSURLConnection here, etc
}

Теперь ваши методы-делегаты должны будут передать массив следующим образом:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
{
    //  parse data to array of objects
   if( _completionHandler )
        _completionHandler(yourNSArrayInstance);
}

Наконец, ваш вызывающий класс попросит анализатор выполнить синтаксический анализ следующим образом:

[myParserClassInstance parseWithCompletionHandler:^(NSArray *jsonObjs)^{
    //  do something with the objects returned to you.
}];

Кроме того, не забудьте Block_release ваш блок завершения ivar в вашем классе синтаксического анализатора в dealloc

Но если вы не хотите иметь дело с блоками, то просто шаблон делегата, в котором ваш класс содержит ссылку на класс, которому вы хотите передать данные.

...