iOS 开发中一些常见的错误(一)

前言

每次写一些东西,总会碰到各种各样的错误.希望把他们整理出来,附上解决的办法.
由于错误实在是太多了,这里就以自己遇到的一系列的坑.碰到了就记录起来.希望帮到大家

简介

话不多说,直接开始吧.楼主最近在写一个简单的旅游app 用到了轮播图 在TableView中异步加载图片的问题.nib和storyboard的问题.frame在AutoLayoutx下错位.分页数据加载等的很多问题

ScrollView + NavigationController ScrolleView显示错位

scrollView图片显示错位

在我们使用ScrollView的时候,在AutoLayout下你约束好了ScrollView,但是你在ViewController 中指定了ContentSize的大小. 然后设置contentOffSet来展示你的视图

<strong>注意:如果你的视图恰好处于NavigationController中的话,你会发现不管你怎么设置contentOffSet 图片的位置始终不是处于一个理想的状态.你可能发现你的contentOffSet 是正确的,不然你会一直陷进去去调整你的contentOffSet的那个点位置</strong>

解释:只要scrollView是其父视图上的第一个子视图,且navigationBar不隐藏的情况下,添加到scrollView里的视图,都会默认下移64个像素。这就是导致你设置contentOffSet始终无法正确显示的原因

解决:在ViewDidLoad 中加上这行代码

 self.automaticallyAdjustsScrollViewInsets = NO; //自动滚动调整

更详细的解释在这里:http://www.cocoachina.com/bbs/read.php?tid-246393.html

加入代码之后

TableView的图片异步加载错乱和TableView分页

我们都知道为了提高app流畅度,我们不可能把一些费时的工作(如:获取网络图片)放在主线程中去进行,这就会造成我们的主线程停下来开始执行这些费时的操作,主线程会阻塞.我们最简单的想起来提高app响应速度的就是将这些网络相关的操作放在其他线程去异步的进行.这就有了我们接下来的错误:<strong>UITableView异步加载图片,图片显示错位</strong>

原谅我无法附上图片来帮助大家更好的理解

解释:TableView一次只能显示5行的图片,在所有图片都加载完后,滚动TableView,让隐藏在下面的行显示在屏幕上,而这些行(比如6行)的图像会先显示第1行的图片,然后在显示属于它自己的图片。以此类推,后面的行都会出现这样的问题!! 即使我们在所有行的图片都还没有下载完成的时候,滚动TableView,让第11行、12行等出现在屏幕上,但它们依旧会先显示错误的图片,然后再显示正确的图片。这就是错误原因TableView的重用机制导致

具体的解释:http://blog.csdn.net/xhl916235259/article/details/48898989

解决方法:

  1. 最简单的方法:把图片的url放入cell中,异步加载完成的时候判断其url是否与cell内的相同,相同的时候再setImage.

细点说你可以自定义cell类,每个cell有自己的url属性.当你加载图片完成的时候,拿出来url和cell的url属性进行对比.虽然cell是可以重用的,但是每个cell都有唯一的url标识.如果两个url相等,这个时候再去设置图片就可以了

  1. 使用:SDWebImage 直接解决这些问题,不用再关心图片异步等的问题

分页加载

很多时候我们都是和后台程序员一起开发程序.由于数据太多,所以使用了分页的方法去把一个庞大的数据分割成一页一页的.那么我们的TableView如何分页?总是出错?

思路:先简单的说一下思路吧,假设一页数据有10个,那我们的单元格可以设置为11个,最后一个设置为加载更多,使用这个方法去触发一次新的网络请求来获取新的一页的数据.然后再将这些数据添加到我们的数据模型中.

一步步的详细的说:这里以我的app为例

  1. 首先我们要用一个容器来存放我们获取到的数据(一般都是JSON).我们使用NSMutableArray(因为我们以后还要往后面添加)

     @interface SceneryViewController ()
     {
         NSMutableArray *item; //存放数据的可变的容器
     }
    
  2. 我们需要填充模型

-(void)getInformatioin{  
    self.helper = [[AFNetHelper alloc]init];
    NSString *baseURL = DATASOURCEURL;
    item = [NSMutableArray arrayWithCapacity:20]; //初始化模型
    for(int i = 0;i < page;i++)  //page:用于记录当前第几页的一个变量,初始化为1
  {
        NSString *url = [NSString stringWithFormat:@"%@%d",baseURL,i+1];
        NSLog(@"%@",url);
        [self.helper modelTransfrom:url block:^(NSString * toJSONString) {
        NSError * error;
        self.model = [[SceneryModel alloc]initWithString:toJSONString error:&error];
        [item  addObjectsFromArray:self.model.data];//填充模型,将我们的数据填进去
    }];
    }     
}

3.填充完模型我们需要设置相关的TabelView了

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
     return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [item count] + 1;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    if(indexPath.row == item.count)
    {
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellbasic" forIndexPath:indexPath];
        if (page == 3)
        {
            cell.textLabel.text = @"没有更多了";
        }
        else
        {
            cell.textLabel.text = @"加载更多";
        }
        return cell;
    }

    else  
    {
    SceneryCell * cell = [SceneryCell cellForRowInSceneryCell:indexPath tableView:tableView model:item];
    return cell;
    }

}

这就是我们最熟悉的TableViewDataSource 协议了,我们判断当前行是不是最后一行.最后一行负责加载数据

4.接下来我们点击最后一行来触发加载下一页的数据获取
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == [item count])
{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellbasic" forIndexPath:indexPath];
if (page == 3) //卤煮这里的分页而为三页,所以page = 3时什么都不错
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}else
{
cell.textLabel.text=@"loading more …";
[self performSelectorInBackground:@selector(loadMore withObject:nil]; //在后台执行loadmore方法 这就是我们的加载更多
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(@"select %ld now indexpath is :%lu ",(long)indexPath.row,(unsigned long)item.count);
}

}

5.触发网络请求 获取下一页的数据

    -(void)loadMore
    {
      page = page+1;
      NSString *baseURL = DATASOURCEURL;
      NSString *url = [NSString stringWithFormat:@"%@%d",baseURL,page];
      [self.helper modelTransfrom:url block:^(NSString * toJSONString) {
      NSError * error;    
      SceneryModel *moreData = [[SceneryModel alloc]initWithString:toJSONString error:&error];    
      NSMutableArray * more = moreData.data;      
      [self performSelectorOnMainThread:@selector(appendTableWith:) withObject:more waitUntilDone:NO];

        }];

    }

我们在后台进行网络数据的获取,拿到了下一页的数据,接下来要添加到我们的容器中.接下来需要在主线程中去进行

6.数据填充

-(void) appendTableWith:(NSMutableArray *)data
{
      for (int i=0;i<[data count];i++) {
          [item addObject:[data objectAtIndex:i]];
      }
      NSMutableArray *insertIndexPaths = [NSMutableArray arrayWithCapacity:10];
      for (int ind = 0; ind < [data count]; ind++) {
      NSIndexPath    *newPath =  [NSIndexPath indexPathForRow:[item indexOfObject:[data objectAtIndex:ind]] inSection:0];
      [insertIndexPaths addObject:newPath];
      }  
      [self.tableview insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationFade];

}

我们在填充完了数据之后,还需要为这些数据添加IndexPath ,否则你可能出现数组越界的错误. 所以我们更新完模型之后,为这些数据分配indePath,然后把这些插入到我们的tableView中.这样我们的分页加载就大功告成了

最后AFNetWorking的一些问题

一个老生常谈的错误了:

NSLocalizedDescription=Request failed: unacceptable content-type: text/html}
AFNetworking 默认不支持text/html

在自己的代码处加上这句代码:

manager.responseSerializer.acceptableContentType =  [NSSet setWithObject:@"text/html"];setWithObject:@"text/html"];

详细的看这里:http://blog.csdn.net/nyh1006/article/details/25068255

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容