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杯。ペース半減。体重はそれほど落ちず。