您的位置:首页 > 移动开发 > IOS开发

iOS 开发中遇到的问题

2015-10-15 09:54 405 查看
1. 关于纠结很久的KVO崩溃问题,其真正原因是,在删除roomItem的KVO之前,将这个对象已经赋值为nil,所以实际上并没有删除他的observer,因此而崩溃;长时间纠结的原因是受.cxx_destruct影响了思路

2.拷贝block

因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。

3.移除observer

Observing 一个已经deallocate的对象不会引起程序crash,但是notifying 一个已经deallocated 的observer会引起程序的crash。这就是为什么要在dealloc 中加入removeObserver:。所以addObserver与 removeObserver一定要成对出现。一般情况下,在init方法中开始observing, 在dealloc中结束observing。
The notification center does not retain its observers, therefore, you must ensure that you unregister observers (using removeObserver: or removeObserver:name:object:) before they are deallocated. (If you don't, you will generate a runtime error if the center sends a message to a freed object.)

4.在拖动时使用NSTimer

在开启一个NSTimer实质上是在当前的runloop中注册了一个新的事件源,而当scrollView滚动的时候,当前的MainRunLoop是处于UITrackingRunLoopMode的模式下,在这个模式下,是不会处理NSDefaultRunLoopMode的消息(因为RunLoop Mode不一样),要想在scrollView滚动的同时也接受其它runloop的消息,我们需要改变两者之间的runloopmode.
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

5. 方法 performSelectorOnMainThread: withObject: waitUntilDone:中waitUntilDone:为YES时,会阻塞在当前线程,等目标线程的队列中的任务完成之后才会继续运行

6.兼容使用instancetype类型
#ifndef MB_INSTANCETYPE
#if __has_feature(objc_instancetype)
#define MB_INSTANCETYPE instancetype
#else
#define MB_INSTANCETYPE id
#endif
#endif

7.方法- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(7_0)参数解析
NSStringDrawingTruncatesLastVisibleLine如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。 如果指定了NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略。NSStringDrawingUsesFontLeading计算行高时使用行间距。(译者注:字体大小+行间距=行高)
NSStringDrawingUsesLineFragmentOrigin,那么整个文本将以每行组成的矩形为单位计算整个文本的尺寸。
NSStringDrawingUsesDeviceMetrics
计算布局时使用图元字形(而不是印刷字体)。
context:context上下文。包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。该参数可为 nil

8.主线程:一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”
主线程的主要作用
显示\刷新UI界面
处理UI事件(比如点击事件、滚动事件、拖拽事件等)
(1)在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新

(2)只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义

9.在UisearchBar中一直显示Xbutton: UITextField* textField = [searchBar valueForKey:@"_searchField"]; textField.clearButtonMode = UITextFieldViewModeNever;

10.(KVC)获取UISearchBar中的textField:UITextField* textField = [searchBar valueForKey:@"_searchField"];

  获取UITextField中的clearButton:UIButton *clearButton = [textField valueForKey:@"_clearButton"];

11. storyboard预览

WWDC 2013 session 406 中视频说起,开启辅佐助预览窗心,方式以下: 1.挑选须要预览的view 2.面击左上角 related files 按钮 3.按住键盘的 control option(alt)键,面击preview 选项中的storyboard选项 ;又或者可以按住 shift option键,点击preview,弹出一个窗口,双击"+"就会打开预览界面,通过这个方式可以打开多个预览界面; 选择Double Length Pseudolanguage使label等中的文字都增加一倍,检查界面效果 (ps:布局可参看链接/article/1225903.html)

12.添加获取用户位置权限的提示文字:在App的 info.plist 中添加 NSLocationWhenInUseUsageDescription 或 NSLocationAlwaysUsageDescription 为新键,然后输入告知用户请求许可的字符串。例如:“显示附近的物品项需要获取您的位置。”

13. 浮点数在计算机中的存储方式就决定了它是有误差,如果你需要精确的计算,使用[NSDecimalNumber decimalNumberWithString:]来得到一个NSDecimalNumber,可以通过这个类的函数进行加减乘除运算。

14.iOS扩展属性:category可以扩展类的方法,但是不能扩张类的属性。如果要扩展类的属性,可以用associative,这个相对于category来说用的比较少,而且他还用到运行时编程,必须使用<obj/runtime.h>,使用objc_getAssociatedObject,objc_setAssociatedObject以及objc_removeAssociatedObjects

15.

UITableView提供了一个批量操作的特性,这个功能在一次进行多个row或者scetion的删除,插入,获取更新多个cell内容的时候特别好用。所有的批量操作需要包含在beginUpdates和endUpdates块中,否则会出现异常。在批量操作时,不管代码中先写的添加操作还是删除操作,添加操作都会被推迟执行,直到这个块中所有的删除操作都执行完以后,才会执行添加操作。

16. Scroll view 没有固定的高度和宽度。
Scroll View 的 宽度和高度由其内容所决定(即 Scroll View 的 contentSize 所决定) 。
内容的大小必须不依赖于 Scroll View 的尺寸。例如,Content1,Content2,Content3 不能包含任何与 Container View 相关的 top,bottom,left 和 right 的布局约束。只能包含固定宽度和高度的约束(每个约束至少在得在其中之一上定义)。如果任何一个 content view 都不包含这些约束,则它们的大小将依赖于 Scroll View(因为它们被绑定到 Scroll View 的边距),但 Scroll View 又依赖于内容的尺寸,这就导致矛盾冲突。
ScrollView 必须至少有一个内容绑定它的四条边,例如 top,left,right,bottom。这样 ScrollView 才能知道它的内容的边界在哪里,即 Scroll View 的 ContentSize。

17.将controller的view添加到其他视图上时,如果没有将控制器添加为对应的子控制器,并且没有持有这个控制器的成员变量,那么这个控制器就会被释放掉,对应的控制器的view也会被释放掉,这时如果在对这个view(虽然释放掉了,但是如果之前显示在界面上,那么他仍然显示在界面上)进行操作,程序就会崩溃;这就是为什么在其中添加timer就不会崩溃的原因,这是因为timer持有了控制器。

18. NSTimer中的fire方法的作用是使定时器立即触发,但是仅对循坏的定时器起作用,对一次运行的定时器没有作用;这个方法不会打乱循环执行的时间,也就是对循环执行没有影响。

19.**Autolayout布局下,要使用transform做动画效果,使用Layer的transform,并且使用图层动画,不能使用视图动画。

20.iOS7系统中UIAlertView崩溃问题,UIAlertView delegate is @property(nonatomic, assign) id delegate, so ensure alertView.delegate = nil when delegate is dealloced. 就是因为UIAlertView的代理被释放之后,没有置为空,所以造成崩溃。

21.Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x7fff395245e0' 这种崩溃往往是因为想访问数组的元素,但是消息却发送给一个字符串(NSString)对象,所以可以查找数组(有可能也是字典)访问的地方,判断是否真正是数组对象。

22.C语言的static修饰的函数作用:

 1. 静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多。
2. 关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。

*23.去掉项目中的警告信息(#pragma GCC diagnostic ignored "-Wunused-variable"):http://www.dbp-consulting.com/tutorials/SuppressingGCCWarnings.html

24.LanuchScreen在iOS8之后的系统中才能使用,之前的系统是不支持它的;iOS9之后http不能使用,而是被https代替,如果在iOS9中仍然想使用http,可以参考这个设置:https://segmentfault.com/a/1190000002933776

*25.苹果的根证书过期造成的证书不能使用的问题,请参看链接:http://www.jianshu.com/p/6bf5a30553bf

26.如何使用随机数,如何产生一个真正的随机数,参看链接:http://nshipster.cn/random/ /article/4807498.html

27.多工程联编的配置问题:https://www.ganlvji.com/xcode_subproject_project_dependency/

28.弹性动画+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRation initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion的参数解析http://www.renfei.org/blog/ios-8-spring-animation.html

29.去掉tabBar上面的一条细线:self.tabBar.backgroundImage = [[UIImage alloc] init]; self.tabBar.shadowImage = [[UIImage alloc] init];

30.设置StatusBar不起作用的原因:info.plist 文件中,View controller-based status bar appearance项设为YES,则View controller对status bar的设置优先级高于application的设置。为NO则以application的设置为准,view controller的prefersStatusBarHidden方法无效,是根本不会被调用的。设置为YES后,在info.plist中再加入key为statue bar style的键值对就可以全局改变statue bar的样式。

31.UILabel在Autolayout下的多行显示参考:http://www.kdfly.com/?p=160

32.Content Hugging 和 Content Compression Resistance和属性的解析,参看:http://blog.csdn.net/yongyinmg/article/details/39526207

33. 在iOS7中,UIViewController还提供了一个 automaticallyAdjustsScrollViewInsets 属性。它可以使得scroll view的上下部分仍然在各种Bar的后面以半透明的形式显示出来,同时scroll的主题内容不被bar遮盖。在实际使用的时候,本人发现并不是任何时候都是这样的,能够生效的前提条件是UIScrollView对象是作为content view controller的root view或者是view0。

34.iOS使用定位服务,弹出提示框的提示文字设置:http://blog.devzeng.com/blog/ios8-corelocation-framework.html

35.更改应用使用硬件的权限,应用崩溃问题请参考:http://www.jianshu.com/p/ada52c520ccb

36.文字描边代码:

//继承UILabel以后重载drawTextInRect
- (void)drawTextInRect:(CGRect)rect {

CGSize shadowOffset = self.shadowOffset;
UIColor *textColor = self.textColor;

CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 1);
CGContextSetLineJoin(c, kCGLineJoinRound);

CGContextSetTextDrawingMode(c, kCGTextStroke);
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];

CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = textColor;
self.shadowOffset = CGSizeMake(0, 0);
[super drawTextInRect:rect];

self.shadowOffset = shadowOffset;

}
//该片段来自于http://outofmemory.cn

*37.在bundle中使用图片,图片在编译后生成.tiff文件的问题:默认情况下,有两种resolutions的图片可以产生一些有趣的现象。例如,当你导入一个retina @2x版本的图片时,普通版的和Retina版的将会合并成一个多resolution的TIFF(标签图像文件格式,Tagged Image File Format)。这不是一件好事。搜索hidpi将COMBINE_HIDPI_IMAGES设置为NO。

38.tintColor属性对UIButton不起作用的原因是创建button的类型要使用UIButtonTypeSystem

39.NavitatiionController改变返回按钮后,手势失效的解决方法是添加

if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {

self.interactivePopGestureRecognizer.delegate = weakSelf;

}

40.使用位置时要显示的请求授权,且在设置中更改授权状态后,返回app,程序不会崩溃;使用相机、相册、麦克风时,不用必须显示的请求授权,在使用时系统会自动提示授权,且在设置中更改授权状态后,返回app,程序会崩溃,当然使用相机、相册、麦克风时,也可以显示的请求用户授权,不一定非要等到使用的时候由系统提示授权。

41.Cookie是放在请求头中的,https://www.skyfox.org/ios-url-request-cookie.html http://blog.csdn.net/chun799/article/details/17206907
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: