iOS实例变量未在块内初始化

时间:2013-05-19 18:04:43

标签: iphone ios objective-c objective-c-blocks parse-platform

我使用parse.com作为我的应用程序的后端。 我需要从后端获取信息并使用此信息初始化实例。 我使用此代码来执行此操作:

    - (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设置为null, 我究竟做错了什么? 谢谢!

2 个答案:

答案 0 :(得分:0)

非常确定原因在于您调用的方法名称-getObjectInBackgroundWithId:block:(它指定了 InBackground ,这表明该块在稍后阶段而不是立即被调用)

这表示你最终得到self == nil(因为你没有在方法中调用任何其他初始化器。

对象的初始化必须是同步的。

答案 1 :(得分: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:之前已经完成了init。

如果在init方法返回之前需要完成解析位,则应该:

  1. 调用解析以在对象上调用init之前获取详细信息
  2. 使用getObjectWithId: ---不推荐,因为这会阻止init中的线程,坏主意