1

我从 RestKit 开始,我设法进行查询并将其加载到 TableViewController 中。

查询返回:idTask、nameTask 和assignedUserId。

直到这里一切正常,完美运行。当我想从其assignedUserID(这是其他请求)加载用户名时,问题就来了。

我执行以下操作:

- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
    [self.refreshControl endRefreshing];
    NSLog(@"%d Tasks received", objects.count);
    self.resultsArray = objects;

    Task *task;
    for (int i=0; i<self.resultsArray.count; i++){
        task=(Task*) [self.resultsArray objectAtIndex:i];
        task.user= [[User alloc]init];
        [task.user getUserDetails:task.idUser];
    }
    [self.resultsTable reloadData];
}

对于收费用户调用我的班级的每项任务,我在其上加载数据,但该用户无法在我的班级工作中使用它。他的属性总是NULL。

如何加载多个对象?

Mi 类用户是这样的:#import "User.h"

@implementation User


-(User *) getUserDetails:(NSNumber *)idUsuario{
    [self loadUsersAssigned:idUsuario];
    return self;
}

-(void) loadUsersAssigned:(NSNumber *)idUsuario
{
    NSString *urlGetUser;
    urlGetUser = [NSString stringWithFormat:@"MY URL", idUsuario,[[NSUserDefaults standardUserDefaults] objectForKey:@"userAccessToken"]];
    //Load objects from url
    RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[User class]];

    //Set relations (keys)
    [objectMapping mapKeyPath:@"id" toAttribute:@"idUser"];
    [objectMapping mapKeyPath:@"first_name" toAttribute:@"name"];
    [objectMapping mapKeyPath:@"last_name" toAttribute:@"lastName"];

    RKObjectManager* manager = [RKObjectManager sharedManager];

    [manager loadObjectsAtResourcePath:urlGetUser delegate:self block:^(RKObjectLoader* loader){
        loader.objectMapping = objectMapping;
        [loader setCachePolicy:RKRequestCachePolicyNone];
    }];
}

- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
    NSLog(@"Users recived: %d",objects.count);
    NSArray *result = objects;
    User *u = [result objectAtIndex:0];
    self.idUser=u.idUser;
    self.name=u.name;
    self.lastName=u.lastName;
}


- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error
{
    //    [self.refreshControl endRefreshing];
    //    NSLog(@"Error: %@", error.description);
}

@end

更新:

你怎么说,我认为我应该使用积木,但我不知道怎么做,因为我从不使用它。

我的对象正在返回正确的数据,但它来得太晚了。我给你看我的日志和我的代码。

我已经修改了你解释的循环。是这样的:

int i=1;
for (Task *task in [self resultsArray]){
    NSLog(@"--- begin iteration %d ---",i);
    task.user= [[User alloc]init];
    task.user =[task.user getUserDetails:[task idUser]];
    NSLog(@"task inside objectLoader of Task id:%@ - name:%@ - lastname:%@",task.user.idUser,task.user.name,task.user.lastName);
    NSLog(@"--- end iteration %d ---",i);
    i++;
}

然后日志显示:

2013-01-29 10:38:32.075 --- begin iteration 1 ---
2013-01-29 10:38:32.075 task inside objectLoader of Task id:(null) - name:(null) - lastname:(null)
2013-01-29 10:38:32.076 --- end iteration 1 ---
2013-01-29 10:38:32.076 --- begin iteration 2 ---
2013-01-29 10:38:32.077 task inside objectLoader of Task id:(null) - name:(null) - lastname:(null)
2013-01-29 10:38:32.078 --- end iteration 2 ---
2013-01-29 10:38:33.570 Users recived: 1
2013-01-29 10:38:33.570 Object loader of user: 522327,Xavi,Sanchez
2013-01-29 10:38:33.640 Users recived: 1
2013-01-29 10:38:33.640 Object loader of user: 522327,Xavi,Sanchez

当循环完成时,用户对象被加载。在它之前,用户的对象是空的。我需要使用块或类似的东西来等到用户对象正在加载。

4

1 回答 1

0

异步请求

您正在发出异步请求并且您希望以同步方式运行,您在这里缺少很多概念。保持解释简单,这意味着您不能期望与您的代码同时获得请求的对象。正如你所注意到的,它总是会追上它。在您发出请求几秒钟后,您将在objectLoader didLoadObjects方法上收到对象。这些秒是您的机器向 Internet 询问某些内容并获得响应的时间。

天真的解决方案是将您希望使用从请求中获得的对象执行的逻辑移动到用户的objectLoader didLoadObjects中。但这是一个非常糟糕的主意,因为你正在混合一些东西。

阅读有关如何在objective-c 上使用块并更改获取对象的方式以避免对象耦合的信息。你真的应该学习如何在 RestKit 上使用块。检查这个问题,它可以帮助你。

未获取用户信息

好吧,首先,我认为您应该检查服务器是否正在返回某些内容,因此如果由于 URL 错误而发出错误请求,则可以丢弃。

添加以下代码以检查网络发生了什么,它将启用网络日志。

RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);

如果您得到了很好的响应,请检查映射过程后数据是如何转换为对象的:

RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);

这应该指出什么是错的。

如果您在日志中没有得到任何内容,则问题是您的请求没有完成。告诉我你有什么可以进一步帮助你。

加载多个对象

每个请求都是昂贵的。现在,您正在执行一项请求以获取任务,并且针对这些任务的每个用户执行一项请求。如果您有 N 个任务,则您正在发出 N+1 个请求。那是没有效率的。如果所有任务都链接相同的用户,情况会变得更糟。

您应该做的是修改服务(如果可以的话),在界面上添加您需要的用户信息,在您的情况下,添加用户名,并在一个请求中获取所有内容。如果您需要一位用户的更多详细信息,您将需要包含完整用户信息的服务,并且您提出请求以防万一,但并非总是如此。

建议

我的建议是您使用来处理请求,而不是委托/协议方式。根据我的经验,在这种情况下与代表合作总是令人头疼,而且代码会更容易阅读。

forin 而不是 for,它更干净

而不是您拥有的 for 循环,请尝试以下操作:

for (Task *task in [self resultArray]) {
    task.user = [[User alloc] init];
    [[task user] getUserDetails:[task idUser]];
}
于 2013-01-28T13:33:52.137 回答