2013-05-19 3 views
-1

Я использую parse.com в качестве backend для своего приложения. Мне нужно получить информацию из моего бэкэнда и запустить экземпляр с этой информацией. я использую этот код для того, чтобы сделать это:переменные экземпляра iOS, не инициализированные изнутри блока

- (id) initWithTeamId:(NSString *)teamId 
{ 
__block NSString *str; 
__block FrFTeam *blockSelf = self; 
PFQuery *query = [PFQuery queryWithClassName:@"teams"]; 
[query getObjectInBackgroundWithId:teamId block:^(PFObject *object, NSError *error) { 
    str = [object objectForKey:@"teamName"]; 
    (void)[blockSelf initWithName:str players:nil thumb:nil]; 
}]; 

return self; 
} 

, когда этот код выполняется self.name устанавливается в нуль, что я делаю не так? спасибо!

ответ

0

Попробуйте этот код:.

// call init on the object, then setup the team id 
- (id)initWithTeamId:(NSString *)teamId 
{ 
    self = [super init]; 
    if (self) { 
     [self setupWithTeamId:teamId]; 
    } 

    return self; 
} 

- (void) setupWithTeamId:(NSString *)teamId 
{ 
    __weak FrFTeam *blockSelf = self; 

    PFQuery *query = [PFQuery queryWithClassName:@"teams"]; 
    [query getObjectInBackgroundWithId:teamId block:^(PFObject *object, NSError *error) { 
     NSString *name = [object objectForKey:@"teamName"]; 
     NSLog(@"Received name: %@ from object: %@", name, object); 
     [blockSelf setName:name]; 
    }]; 
} 

Затем измените имя метода с initWithName:..., потому что это не действительно метод init, потому что вы уже выполнили инициализацию перед вызовом setupWithTeamId:.

Если вам нужно немного синтаксического анализа должно быть сделано до возврата метода инициализации, вы должны:

  1. вызовов синтаксического анализа, чтобы получить подробную информацию перед вызовом инициализации на объекте
  2. Использование getObjectWithId: --- не рекомендуется так как это блокирует поток в init, плохая идея
+0

спасибо, это все еще не работает, после инициализации: FrFTeam * tmpTeam = [[FrFTeam alloc] init]; и используя ваш метод: [tmpTeam setupWithTeamId: team.objectId]; имя по-прежнему равно нулю –

+0

Сразу после вызова этого метода оно равно nil (и должно быть), так как обработчик завершения в лучшем случае запланирован в END текущей runloop, нет возможности сразу заполнить поле имени без блокировки для запроса. Мое предложение KVO, вы можете прослушать изменение имени (если оно настроено правильно) и действовать при изменении. –

0

Довольно уверен, что причина заключается в имени метода вы звоните -getObjectInBackgroundWithId:block: (он определяет InBackground, который предлагает блок называется на более поздней стадии и не сразу)

Это говорит о том, что вы в конечном итоге с . самостоятельно == ноль (как вы не вызывая какой-либо другой инициализатора в методе

инициализация объекта должен быть синхронным

+0

Есть ли способ получить данные асинхронными и синхронными init? –

+0

Только если вы обрабатываете init в фоновом потоке, но сам init должен быть синхронным. Я замечаю, что вы передаете довольно много нулей вашему инициализатору, является ли строка имени даже необходимой для инициализации объекта? Возможно, вы можете его инициализировать, и THEN начнет загрузку (асинхронно), которая заполняет поле имени? Это то, что дает другой ответ в приведенном коде. –

+0

«Это будет означать, что вы закончите с self == nil» Нет. Если вы посмотрите на код OP, то, что возвращается из метода initWithTeamId: ', является' self', то есть объект, на который он вызывается. Не 'nil'. – newacct

Смежные вопросы