iOS 工作遇到问题记录

1、UITableView的scrollDelegate问题

下午遇到一个奇怪的问题,之前都没有注意过,由于A VC中要实现tableView和其他View位置的联动,
所以实现了tableView的delegate中的scrollViewDidScroll方法,结果在点击商品push 商品详情VC B 的时候,问题出现了。

问题表现:
在调用[self.navigationController pushViewController:productDetailVC animated:YES];
时发现VC A中的tableView总是会滚动到顶部(contentOffset被修改了)

看了半天也没发现问题,后面在scrollViewDidScroll的位置加了一个断点,发现在navigationController在Push VC B的过程中,系统会调用一次VC A中tableView的scrollViewDidScroll方法,关键是这时调用中传入的contentOffset是有问题的(0,-contentInset.y),所以导致了VC A中的tableView会自动返回头部

解决方法:在VC A的viewWillDisappear的时候设置tableView的delegate为nil,同时在viewWillAppear中再把tableView的delegate设置回来,这个问题就被解决掉了。
all in all 问题很奇怪,希望大家不再被同样的问题困扰

2、UIView的exclusiveTouch属性

通过设置[selfsetExclusiveTouch:YES];可以达到同一界面上多个控件接受事件时的排他性,从而避免一些问题。

3、UIScrollView和UITableView嵌套时点击statusBar,scrollView不反回头部的问题

苹果在UIScrollView头文件的注释可以清楚的解决我们的困惑

// When the user taps the status bar, the scroll view beneath the touch which is closest to the status bar will be scrolled to top, but only if its `scrollsToTop` property is YES, its delegate does not return NO from `shouldScrollViewScrollToTop`, and it is not already at the top.

// On iPhone, we execute this gesture only if there‘s one on-screen scroll view with `scrollsToTop` == YES. If more than one is found, none will be scrolled.

@property(nonatomic) BOOL  scrollsToTop;          // default is YES.

4、JSON Kit数据转换问题

json是很常用的网络数据包格式,客户端和服务端之间经常使用json来传输数据。对于一些字典类型的数据,如果某项数据为空,则会传‘<null>‘,使用JsonKit转换以后会生出相应的[NSNull null]对象,而这种对象对于iOS来说并不是十分安全的,例如约定好商品的某一项字段为string类型,结果JSON Kit转换为[NSNull null],这个时候如果不加判断就当做是NSString处理就会存在问题。所以对于这种数据类型直接转换为nil会更加安全,转换方法如下:

#define PASS_NULL_TO_NIL(instance) (([instance isKindOfClass:[NSNull class]]) ? nil : instance)

针对nil调用任何方法基本上都是安全的。

 5、iOS 7中系统自定义VC右滑返回特性不生效

iOS 7开始系统新增了UINavigationController中VC层级右滑返回上一级的特性,该特性默认是打开的。但是在项目中有一个自定义VC中该特性无效,排查半天定位到问题如下:

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_bar_back.png"]
                                                                        style:UIBarButtonItemStylePlain
                                                                        target:self
                                                                        action:@selector(backAction:)];

初一看这段代码没有任何问题,只是简单的自定义返回按钮。但是问题就处在这里,只要自定义了leftItem右滑返回上一层级就会实效。

因为我这个VC中UI比较复杂,ScrollView,tableView各种嵌套,因此一开始还怀疑是不是手势冲突导致的,后来发现右滑返回属性压根就和我们能接触的手势无关。将上述代码修改为如下代码,问题就解决了。

if (IS_IOS_6) {
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_bar_back.png"]
                                                                                 style:UIBarButtonItemStylePlain
                                                                                target:self
                                                                                action:@selector(backAction:)];
}

只针对iOS 7之前的系统自定义返回按钮,iOS 7及以后直接使用系统的返回图标“<”。

我们也可以直接获取这个手势“interactivePopGestureRecognizer”,做一些定制操作。

更详细的信息可以参考:http://www.cnblogs.com/lexingyu/p/3432444.html

6、UITableViewCell选中保持问题

UITableView中cell的选中态在调用ReloadData以后无法保持,为了做到选中态一直有效,我试着在cellForRowAtIndexPath中恢复选中态,代码如下:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"myAccountMenuCellIdentifier";
    UITableView *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:cellIdentifier];
    }

   ...

    // 恢复选中态
    if (_currentSelectedIndexPath
        && indexPath.row == _currentSelectedIndexPath.row
        && indexPath.section == _currentSelectedIndexPath.section) {
        [cell setSelected:YES animated:NO];
    }
    else {
        [cell setSelected:NO animated:NO];
    }

    return cell;
}

  发现根本不起作用,还尝试着重载了自定义cell的

- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated;

  也是毫无进展,最后终于通过重载reloadData,代码如下:

- (void)reInvokeCurrentMenuItem
{
    [self selectRowAtIndexPath:_currentSelectedIndexPath
                      animated:NO
                scrollPosition:UITableViewScrollPositionNone];

    [self tableView:self didSelectRowAtIndexPath:_currentSelectedIndexPath];
}

  即在每次reload以后都通做一次selectRowAtIndexPath的操作来恢复选中。问题虽然解决了但是这种方法也有潜在风险,比如reload的过程中数据源发生变化,可能之前选中的cell的indexPath已经改变,轻则选中不正确的cell,严重的话如果刷新以后cell个数减少,传入一个过大的indexPath就会造成崩溃。

  so此方法,请君“且用且珍惜”。

7、UITextField当实现了textFieldDidBeginEditing方法以后, Clearbtn不响应,原因是最简单的view覆盖导致事件被拦截了

  如果必须实现delegate,则可以使用设置rightView的方式

  这个问题我最后解决了,说来都不好意思,被别的View盖住了,so出了问题还是得先思考一下是不是自己的问题。

  查这个问题得过程中,我找到一个很好用的GDB调试方法,直接在GDB中输入以下命令即可打印当前App的view层级。

po [[UIWindow keyWindow] recursiveDescription] 

  我知道网上有个收费的工具叫Reveal,可以更炫的查看view层级,好消息是xCode6 Debug自带了可查看view层级的功能。底层的实现机制也是一样,个人偏执的觉得还是命令行打印的更清晰,特别是view层级很多的时候。

8、Block为空是调用会Crush

  昨天碰到一个crash问题,查了一下发现是Block是nil,然后我调用了该Block,程序crash。开始怀疑是不是我的block是在dispatch_async导致的crash,后面测试发现,只要block为nil,调用这个block都会crash。

  简单示例如下:

// 定义一个block类型
typedef void (^CompleteBlock) ();

// 声明一个CompleteBlock类型的变量
CompleteBlock cblock = nil;

cblock();       // 调用会crash
dispatch_async(dispatch_get_main_queue(), ^{
    cblock();   // 调用也会crash
});

  定义一个nil的block,无论怎么调用都会crash,不知道苹果为什么没有做保护,总之以后调用block之前还是先判断一下比较靠谱。

9、UIImagePickerController黑屏问题

  使用UIImagePickerController完成拍照选取时,发现在iOS8上黑屏,其他设备都正常。查了半天才发现原来测试在系统设置中把App的Camera权限关闭了,测试也没有注意到这点。我们一直以为这是iOS 8beta版本的bug,找了半天才发现原来原因很简单。话说回来既然iOS7之后用户可以控制Camera的权限,那么我们的App能不能做的更好,更友好呢,于是查了一下资料发现AVFoundation库提供了检测Camera授权状态的API,所以就有了下面这个函数。

 takePhoto

  代码中显示检测系统是否支持拍照,然后在检测App是否有拍照的权限,最后才是进入拍照界面,防止模拟器调试拍照时Crash,或者真机调试权限关闭时出现的拍照界面一直黑屏的情况。

10、xCode Archive出来的包在本地Organizer中看到的App没有图标的问题

  xcassets的出现大大方便了我们提供App中对应的icon等,使我们再也不用操心icon的各种繁琐命名了,诸如Icon-57.png等。之前也碰到过因为未提供完整的icon导致App被拒的问题,现在这些问题基本上不存在。

  昨天在Archive包以后看到本地Organizer中显示的iPad居然没有图标,再三检查xcassets,发现所有icon都有,不应该有问题啊。后来查找资料发现这可能是xCode的一个bug,本地显示没有图标,但是装到设备上一级提交到AppStore再下载下来都是有图标的,不影响审核和使用,纯粹是显示问题。

  如何解决这个问题,检查App中得xxx-info.plist文件中,添加Icon file属性,并填上非retian和Retian屏幕对应的icon文件名称(文件必须存在,且命名如下),如下图所示:

  再次Archive即可发现,本地的Organizerz中的App有icon了。

时间: 2024-11-05 02:33:49

iOS 工作遇到问题记录的相关文章

iOS工作笔记之NSClassFromString

id myObj = [[NSClassFromString(@"MySpecialClass") alloc] init]; 和 id myObj = [[MySpecialClass alloc] init]; 是一样的.但是,如果你的程序中并不存在MySpecialClass这个类,下面的写法会出错,而上面的写法只是返回一个空对象而已. 因此,在某些情况下,可以使用NSClassFromString来进行你不确定的类的初始化. 比如在iPhone中,NSTask可能就会出现这种情

IOS真机调试记录

首先,登录到http://developer.apple.com/devcenter/ios/index.action,如果已经购买了iPhone Develop Program(iDP),登录进去后,页面右上角会看到如下图所示的页面: 点击第一项:iOS Provisioning Portal,然后会看到下面的页面: 点击进入Certificates,然后看到如下所示的页面: 点击图中的click here to download now,这会下载下来一个AppleWWDRCA.cer文件,这

iOS工作记录9:项目单例(直接拉用)

我就直接用个例子记录: 工程代码记录下来: // //  Ticket.h #import <Foundation/Foundation.h> @interface Ticket : NSObject // 实例化票据的单例 + (Ticket *)sharedTicket; // 在多线程应用中,所有被抢夺资源的属性需要设置为原子属性 // 系统会在多线程抢夺时,保证该属性有且仅有一个线程能够访问 // 注意:使用atomic属性,会降低系统性能,在开发多线程应用时,尽量不要资源 // 另外

iOS工作记录10:清理缓存

我们在做项目开发的时候,经常会遇到设置清理缓存的问题,对于新手经常会考虑到什么数据存储啊,内存之类一大堆无用的想法,其实镔哥认为清理工程的缓存是一件非常简单的事情. 不用多说:见代码,立即大悟: @property (nonatomic, strong) UILabel * cachLabel;//显示缓存有多少m 最后节目显示: cell.cachLabel.text = [NSString stringWithFormat:@"(%.2fM)", [self filePath]];

一年iOS工作经验,如何一举拿下百度、美团、快手等Offer面经(附面试题)

先简单说说我最近的面试经历吧.面试的公司很多,大部分最后都能得到令人满意的结果,我将这些体会记录下来,面了这么多公司,如果不留下什么,那岂不是太浪费了.对于我来说,这也是一次自我检查,在这次面试中总结经验,认清自己,同时希望这些对即将换工作或者打算看看其他机会的你有一些帮助. 关注作者其他文章,可以找到大神交流总部(其实做为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,不管你是小白还是大牛欢迎入驻,大家一起交流学习) 以下的部分有具体的面试经历,也有自己的一些总结面试必备技能和自己的一些感

iOS崩溃前日志记录实现

如何使用Signal 因为错误抛出Signal,必须要专门做Signal处理. 在计算机科学中,信号(英语:Signals)是Unix.类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式.它是一种异步的通知机制,用来提醒进程一个事件已经发生.当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断.如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数. 在项目工程中,要使用 #include <sys/signal.h>

iOS开发架构学习记录

闲着没事看了一些iOS开发架构的视频,简单的介绍了几个常用的架构设计,现将它记录如下,以后有时间再专门写这方面的内容,大家可以看看,感兴趣的就进一步学习. 一.架构基础 1.架构设计的目的 进一步解耦. 2.耦合的方式 1)单例-彼此知道对方的存在 2)delegate-被委托方不知道委托方的存在,委托方知道被委托方的存在 3)通知-双方都不知道对方的存在 二.MVC C可以控制V的渲染,C可以修改M. V可以将用户这边采集到的数据和用户事件反馈给C做进一步的处理,V可以读取到M中的数据进而展示

工作笔记---巡检记录

以下是工作中一些思路实现的笔记,业务需求是: 1.简易日历 2.质押物提交后的一天开始到当前系统时间之间才可以提交质押物 3.没有提交质押物的日期里面的图片以灰色图片站位,已经提交质押物的日期里面的图片以红色图片站位 4.图片点击之后可以出现modal,modal中需要有图片轮播,需要前端删除,后端删除,上传图片,图片上传限制 经验分享: a.后端返回给前端的数据可能比较乱,这个时候需要前端写一个适配器函数,也就是把后端的数据进行转换成前端某一个插件适用的数据结构.适配器函数很好用哦~在工作的其

IOS工作笔记(五)

说明:记录下学习IOS的一些琐碎,有些在现在看起来很简单幼稚,不过权当学习足迹吧! 1.frame的打印,可以用 NSLog(@"%@",NSStringFromCGRect(self.view.frame)); 2.UIButton文字的对齐方式,以左对齐为例 myBtn.titleLabel.textAlignment = NSTextAlignmentLeft;//这种设置方式无效 myBtn.contentHorizontalAlignment = UIControlConte