我从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
当循环结束时,加载用户对象。在它之前,用户的对象为null。我需要使用一个块或类似的东西来等待加载用户对象。
答案 0 :(得分:0)
异步请求
您正在制作异步请求,并且您希望以同步方式运行,这里缺少很多概念。保持解释简单,这意味着您不能期望在代码的同时获取请求的对象。正如你所注意到的那样,它总会随之而来。您将收到 objectLoader didLoadObjects 方法上的对象,之后秒。这些秒数是您的机器在向互联网询问某些内容并获得回复的时间。
天真的解决方案是将您要执行的逻辑与请求中的对象一起移动到用户的 objectLoader didLoadObjects 。但这是一个非常糟糕的主意,因为你在混合东西。
了解如何在objective-c上使用块并更改获取对象的方式,以避免对象耦合。你真的应该学习如何在RestKit上使用块。检查this question,它可以帮到你。
未获取用户信息
嗯,首先,我认为您应该检查服务器是否正在返回某些内容,因此如果您因为网址错误而提出错误请求,则可以放弃。
添加以下代码以检查网络的运行情况,它将启用网络日志。
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
如果您得到了很好的响应,请检查映射过程后数据如何转换为对象:
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
这应该是错误的。
如果您没有在日志上获得任何内容,则问题是您的请求未完成。告诉我你有什么进一步的帮助。
加载多个对象
每个请求都很昂贵。现在,您正在执行一项请求以获取任务,并为每个用户执行一项任务。如果你有N taks,你正在提出N + 1请求。那效率不高。如果所有任务都链接了相同的用户,则会变得最糟糕。
您应该做的是修改服务(如果可以的话),在您的案例中添加您需要的用户信息,添加用户名,并在一个请求中获取所有内容。如果您需要一个用户的更多详细信息,您将需要一个包含完整用户信息的服务,并且您可以根据需要而不是总是提出请求。
<强>推荐强>
我的建议是您使用块来代替委托/协议方式来处理请求。根据我的经验,在这种情况下与代表合作总是很头疼,代码将更容易阅读。
forin而不是for,它更干净
请尝试以下方法,而不是使用for循环:
for (Task *task in [self resultArray]) {
task.user = [[User alloc] init];
[[task user] getUserDetails:[task idUser]];
}