since_idを確定できるのは、lastidがおかわりしたJSONの中に含まれ、且つlastidとJSONの最後のidが等しくない場合なので、それ以外のケースでは、
1.lastidよりおかわりしたJSONの最初のidが小さい場合
2.lastidよりおかわりしたJSONの最後のidが大きい場合
に切り分けて、1の場合はlastidとJSONの最初のidの差分をsince_idに+=し、2の場合は逆に-=して再度おかわりして確定できるまで繰り返していた。さらに1の場合だと+=した際にsince_idがlastidを超えるという馬鹿なケースが起こるので、その場合は前述のとおりid乖離平均にlimit+1をかけた数値を半分(それでも多ければ戻ってくるたびに3分の1、4分の1〜)していた(これを3とする)。
上記アルゴリズムで、たまに(場合によってはしょっちゅう)以下の2パターンの遅延が発生していた。
A.1を数十回繰り返してもなかなかJSONの最初のidがlastidを超えない
B.1と2を行ったり来たり、または1と3を行ったり来たりする
Aについては、まあ待ってれば確定するが、それでも分単位でloadingが終わらないのは精神衛生上よくないしサーバにも優しくない。Bはさらに致命的で、ほぼ無限ループに近い状態になる。
Aは+=する値を倍々してスピードを上げ、Bは行き過ぎた分戻すだけなのでスピードを下げておかわりする。コードは以下のとおり。
- (void)apiTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data{
loadflg=NO;
NSDictionary *bd=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
long long topid=[[[bd valueForKeyPath:@"response.posts.id"]objectAtIndex:0]longLongValue];
int skip=0;
if(offset+limit>250){
if(lastid>topid){
if(adjflg==1){adj2=2;since_id+=(lastid-topid)*adj1++;}
else if(adjflg==2){adj1=2;since_id+=(lastid-topid)/adj2++;}
else since_id+=lastid-topid;
adjflg=1;
if(since_id>=lastid){adj1=2;adj2=2;since_id=lastid-(([[idArr objectAtIndex:0]longLongValue]-[[idArr lastObject]longLongValue])/([idArr count]-1)*(limit+1))/adj3++;}
offsinceval=[NSString stringWithFormat:@"%lld",since_id];[self reqJSON];
return;
}else if(lastid<=[[[bd valueForKeyPath:@"response.posts.id"]lastObject]longLongValue]){
if(adjflg==2){adj2=2;since_id-=(topid-lastid)*adj1++;}
else if(adjflg==1){adj1=2;since_id-=(topid-lastid)/adj2++;}
else since_id-=topid-lastid;
adjflg=2;
offsinceval=[NSString stringWithFormat:@"%lld",since_id];[self reqJSON];
return;
}else{
adjflg=0,adj1=2,adj2=2,adj3=2;
for(id idnum in [bd valueForKeyPath:@"response.posts.id"]){
if(lastid<=[idnum longLongValue]) skip++;
else break;
}
}
}else if(lastid!=0&&lastid<=topid){
offset++;offsinceval=[NSString stringWithFormat:@"%d",offset];[self reqJSON];return;
}
//type別処理は例によって割愛
lastid=[[idArr lastObject]longLongValue];
[self mkSinglePostView];
}
できた。1100postくらいまでは動いてたけどerror code=12が出たのでメモリ関連の処理を調べる。postのuiviewで古いやつは配列から消したほうがいいのかな。
ランは遅かったので7.22km@37:51だけ走った。ラーメンは今月まだ10杯。ペース半減。体重はそれほど落ちず。