iOS 开发中遇到的问题

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:布局可参看链接http://www.cocoachina.com/ios/20141020/9978.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/       http://www.cnblogs.com/rupeng/p/3723018.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 

NSHTTPCookieStorage单件类提供了管理所有NSHTTPCookie对象的接口,在OS X里,cookie是在所有程序*享的,而在iOS中,cookie只在当前应用中有效。

 

42.统计汉字和assic的一小段代码:

- (NSUInteger)unicodeLengthOfString:(NSString *)text
{
    NSUInteger asciiLength = 0;
    
    for (NSUInteger i = 0; i < text.length; i++) {
        unichar uc = [text characterAtIndex: i];
        asciiLength += isascii(uc) ? 1 : 2;
    }
    
    NSUInteger unicodeLength = asciiLength / 2;
    
    if(asciiLength % 2) {
        unicodeLength++;
    }
    return unicodeLength;
}

43.fir.im 只支持两种打包方式,AdHoc、InHouse,AdHoc 就是内测版,InHouse 就是企业版,这里是识别上传的 .ipa 的信息来区分证书类型的,如果想显示企业版,需要用企业证书 InHouse 打包方式来导出 .ipa。

 

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

 

45.设备接到apns发来的通知,应用处理通知有以下几种情况:

1. 应用还没有加载
这时如果点击通知的显示按钮,会调用didFinishLaunchingWithOptions,不会调用didReceiveRemoteNotification方法。
如果点击通知的关闭按钮,再点击应用,只会调用didFinishLaunchingWithOptions方法。

2. 应用在前台(foreground)
这时如果收到通知,会触发didReceiveRemoteNotification方法。

3.应用在后台
(1)此时如果收到通知,点击显示按钮,会调用didReceiveRemoteNotification方法。
(2)点击关闭再点击应用,则上面两个方法都不会被调用这时,只能在applicationWillEnterForeground或者applicationDidBecomeActive,根据发过来通知中的badge进行判断是否有通知,然后发请求获取数据

46.在弹出UIAlertView的同时,调用UINavigationController的pop方法,则pop方法不能生效,放到弹出UIAlertView之前可解决问题

47.删除工程中无用图片的脚本:http://www.jianshu.com/p/17c000d97a74

48.iOS How can I skip compressing one PNG?  答案:Xcode will only optimize PNG image files that it knows about. To prevent a specific PNG from being optimized, you change its file type so Xcode no longer knows it's a PNG. Change the file type from Default - PNG Image to Data in Identity and Type inspector in XCode.

 

49.Compress PNG Files的作用

Compress PNG Files"实际上是将图片像素的颜色信息,转换成iPhone能够更快渲染的格式。
PNG图片采用的颜色空间,一般是RGBA。也就是说,一个像素点的颜色,是由四个分表代表红色,绿色,蓝色,透明度的字节来存储。而iPhone的图像内存,使用的是一种非标准的颜色空间(BGRA,对应的图片格式叫做CgBI))。从读取图片像素点RGBA的信息,到最终计算出,屏幕渲染所需的BGR,会有更大的耗时。如果图片一开始就是以BGR保存的,那渲染时要做的,就仅仅是个简单的内存拷贝操作。因此,在项目进行编译,也就是“Compress PNG Files"时,Xcode会对图片中的颜色信息进行计算转换。假设图片中某个像素是这样的一个颜色(R:0.0,  G:0.0, B:1.0,  A:0.5),那么在编译时,这个像素点会被转换成(B:0.5, G:0.0, R:0.0, A:0.5.大家可以看到,蓝色的部分,已经被乘以50%的透明度。通过这样的预处理,在程序运行时就不用再对颜色进行转换。但是,A(透明值)仍然会保存在图片信息中,这是因为我们的项目可能需要对同个位置的两张图片进行混合,在这种情况下,iPhone就需要通过透明值来计算,最终呈现给用户的,是怎样一个颜色。在iOS项目中,将你的UIImageView属性的opaque (不透明)设为YES,iPhone便会知道图片中的alpha通道是无需使用到的,直接将GRB的值渲染出来即可,省去重计算颜色值的过程。

 

50.几个ARC下的内存注意事项:

1.在UIView动画过程中动画的控件以及其子控件是不能响应事件的,这应该是渲染树导致的(UIView动画执行完成,才会把控件设置为最终的位置);UIView动画的block会使包含其中的成员变量的引用计数加一,但是不会形成循坏引用,并且在父视图销毁时,应该移除了父视图本身及其子视图上的动画,因此,即使子视图在动画过程中,只要父视图销毁了,子视图就销毁了。

2.GCD中block在没有runLoop时会及时释放,当有runLoop时,runLoop会间接持有block中的成员变量,造成不能释放。

3.performSelector:withObject:afterDelay:方法会持有调用该方法的对象和withObjct参数,直到方法完成为止,所以会造成对象不能立即释放。

 

51.原码、反码、补码的详细讲解:http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

52.苹果开发账号的注册流程:http://www.chinaz.com/manage/2016/0317/513437.shtml

53.解决Cound not find Developer Disk Image问题:将想支持的iOS系统版本的文件拷贝到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport目录下即可

54.比较版本号用NSNumericsearch,用nsnumericsearch的话就是逐个取出数字进行比较。先比较第一个数字3和3,相等的话继续比第二个,1和2,显然2比1大,所以字符串2比字符串1大。

55.适配iOS10:http://www.jianshu.com/p/9756992a35ca

56.iOS 将Log日志输出到文件中保存(通过iTunes获取共享的log日志):http://blog.csdn.net/u013250412/article/details/46924381

57.在安装XCode时,命令行工具不会一起安装,需要单独安装。安装方法:1.可以从官网现在命令行工具直接安装 2.在终端中执行命令行中的命令,会自动提示安装命令行工具。

58.iOS内购设置协议、税务和银行业务:http://blog.csdn.net/lxmy2012/article/details/48444731

设置内购的注意事项:(1)只有填写完整协议、税务和银行业务并审核通过后,才能使用苹果的内购功能。   (2)在填写银行信息的时候CNAPS码的查询可以通过网站 http://www.tui78.com/bank/14772.html

59.详细的内购流程:http://blog.csdn.net/jiisd/article/details/50527426

60.iOS推送流程:http://www.jianshu.com/p/4b947569a548  http://superdanny.link/2016/02/02/iOS-Apple-Push-Notification-Service/

61.iOS代码签名探析:https://objccn.io/issue-17-2/

62.URL Scheme详解:http://sspai.com/31500

63.关于友盟渠道使用的那些事:http://bbs.umeng.com/thread-6193-1-1.html

64.iOS 10『限制广告追踪』为移动广告带来哪些影响(IDFA):http://www.admaster.com.cn/?c=downloads&a=view&id=71

65.iOS 中 self 和 super 的区别:http://blog.csdn.net/wangjunling888/article/details/51712504

66.__IPHONE_OS_VERSION_MAX_ALLOWED用来判断是否当前版本SDK“开始”支持或具有某些功能; __IPHONE_OS_VERSION_MIN_REQUIRED用来判断是否当前版本SDK“仍然”支持或具有某些功能。

iOS不同版本适配问题(__IPHONE_OS_VERSION_MAX_ALLOWED 和 __IPHONE_OS_VERSION_MIN_REQUIRED)      http://blog.csdn.net/xyxjn/article/details/40425895

67. Xcode 中的 Aggregate Target 的用处

Xcode defines a special type of target that lets you build a group of targets at once, even if those targets do not depend on each other. An aggregate target has no associated product and no build rules. Instead, an aggregate target depends on each of the targets you want to build together. For example, you may have a group of products that you want to build together. You would create an aggregate target and make it depend on each of the product targets. To build all the products, just build the aggregate target.

An aggregate target may contain a custom Run Script build phase or a Copy Files build phase, but it cannot contain any other build phases. Any build settings that the aggregate target contains are not interpreted but are passed to the build phases that the target contains.