bug的由来
为马克2号(Harvard Mark II)编制程序的葛丽丝·霍波(Grace Hopper)是一位美国海军准将及计算机科学家,同时也是世界最早的一批程序设计师之一,有一天,她在调试设备时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍波诙谐的把程序故障统称为“臭虫(BUG)”,把排除程序故障叫DEBUG,而这奇怪的“称呼”,竟成为后来计算机领域的专业行话。------摘自百度百科
在iOS开发过程中,总会遇到意想不到的bug,导致程序终止运行,抛出异常,这是程序正常运行不允许的,所以我们必须解决。下面罗列的bug是我在开发过程发现的,并且解决掉了,记录下来,时刻警醒自己不要范类似的错误。
1:missing context for method declaration (缺少方法声明的上下文)
这种报错,是因为你你没有把实现的方法写在 @implementation 和 @end 之间导致的。
2:Multiple commands produce...info.plist. Target ... has copy command from ... info.plist
我这是GitHub上下载的MJExtension,然后整个文件手动导入项目中,运行报错。仔细看报错的原因,感觉是info.plist重复了,然后看到MJExtension文件中有一个info.plist,然后删除运行就没问题了。
3: -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'
这类错误,开发初期大家应该是经常遇到,字典里包含了一个空的value导致的:attempt to insert nil object form objects[0].字典里的第一个value是空的。去检查你的字典数据就可。
4:unrecognized selector sent to instance 0x281f39420
这个也是经常遇到的问题了,有野指针,方法没有实现,加载类型不对。在这里,responseObject 返回的是 UIImage类型的,而我加载的还是通过imageWithData方式加载的,很明显类型对不上。
5: this class is not key value coding-compliant for the key _placeholderLabel.textColor.'
在iOS13.0的情况下运行项目,UITextField突然报了这个错:找不到对应的key _placeholderLabel.textColor.
查看了苹果的资料得知,iOS13.0以后,苹果禁止UITextField使用的私有属性修改占位符的颜色及其文字大小,可以使用attributedPlaceholder富文本属性修改。
加个判断即可:
6:使用KVO监听某个属性导致的奔溃,有以下三中情况:
1):调用了addObserver方法监听某个属性值,但是对应的observeValueForKeyPath方法没有实现,就会崩溃到mian.m类里面的main方法。即使你打全局断点,也是还会崩溃在main方法里面。
- (void)addObserver:(NSObject*)observerforKeyPath:(NSString*)keyPathoptions:(NSKeyValueObservingOptions)optionscontext:(nullablevoid*)context;
- (void)observeValueForKeyPath:(nullableNSString*)keyPathofObject:(nullableid)objectchange:(nullableNSDictionary *)changecontext:(nullablevoid*)context;
解决问题就是实现observeValueForKeyPath方法 即可。
2):你没有添加观察者 addObserver 方法,却实现了 observeValueForKeyPath 方法,那么也会崩溃,崩溃在上图片所示位置,而且控制台打印出来任何日志。
3):上面俩个方法你都掉用了,但是在 - (void)dealloc 方法里面没有释放相应的观察属性,则控制器销毁时,也会发生崩溃,崩溃到上面图片所示的位置,而且没有任何崩溃日志。但是通过勾选僵尸调试(Zombile Objects),可以看到崩溃日志:
你会发现有个dealloc,猜测可能在dealloc方法里没有释放KVO观察的属性。经过测试,果然。KVO监听过后,一定要在-(void)dealloc方法里面释放掉(removeObserver)相应的属性
7:使用Cocoapods管理第三方时,编译一下,会报很多警告:
1):在 TARGETS - Build Setings 中搜索 Inhibit All Warnings,No改为Yes(如下图所示),能解决掉很大一部分警告。
2):解决警告 The iOS deployment target is set to 8.0, but the range of supported deployment target versions for this platform is 9.0 to 13.2.3
这是第三方支持的系统版本比我们项目中设置的最低版本还要低导致的,把下面这几句代码添加在Podfile最下方,重新pod install
post_installdo|installer|
installer.pods_project.targets.eachdo|target|
target.build_configurations.eachdo|config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] ='9.0'
end
end
end
8:ld: 2 duplicate symbols for architecture arm64 . clang: error: linker command failed with exit code 1 (use -v to see invocation)
碰到这样的报错信心,基本上可以确定是有重复的文件,看下面图片所示,你会发现有个 HRGetCheckCodeViewController 这个类,你在项目中全局搜索这个类,会发现这个类重复了,删除保留一个就可以了。
9:failed to read asset tags
这种报错,一般有以下俩中问题导致的:
问题一:一般出现在你使用的高版本的Xcode打开了很久之前(比如:俩年前)的项目,或出现这个bug。究其原因,是应为之前的老项目中 Assets.xcassets这个文件缺失造成的,只有个名字,却找不到实体文件。直接删除 Assets.xcassets 这个就好了,然后在添加一个新的 Assets.xcassets文件即可。
问题二:可能是多出了个Assets.xcassets,项目全局搜下有没有同名文件,删了那个就好
10:The run destination My iPhone-Test is not valid for Running the scheme 'Masonry iOS Examples'.
出现这种情况,根据提示可知,是应为你展示代码设备版本比较低,而开发工具上设置的版本比较高导致的。有以下俩中解决方法:
1:把你的设备进行版本更新,升级到新版本即可;
2:修改Xcode中工程配置,修改成设置上显示的版本即可。如下所示:
11: Multiple commands produce '/Users/LYH/Library/Developer/Xcode/DerivedData/MasonryDemo-bhnvzurrqhbvreeyxicjfdbloijx/Build/Products/Debug-iphoneos/MasonryDemo.app/Info.plist'
这种报错,通过下图所示的方式打开可以看到详细的描述
根据详细的描述,每段后面都有一个info.plist,我就全局搜索这info.plist,结果发现这个info.plist有俩个,其中一个是项目中自带的,另外一个是手动导入的第三库里面,很显然,是应为多余了一个info.plist导致的。所以把第三方库中的info.plist删掉即可解决问题。
12:[__NSCFConstantString CGColor]: unrecognized selector sent to instance
根据提示和经验可知,这种情况下应该是 1:方法没有实现;2:属性设置有误。然后去代码中排查,结果发现我把label设置的背景色设置为字符串了,导致了上述问题。
13:Mansory约束错误导致的:Constraint improperly relates anchors of incompatible types
代码中的错误
原来我是想约束centerY的,结果错写成center了导致的。
14:打包时报错:Command PhaseScriptExecution failed with a nonzero exit code
这是因为Xcode10开发工具下是默认选中的最新的New Build System(Default),在这个编译系统的环境下,打包的CI脚本一直会报错。
解决方案如下:
Save As Workspace 是有Cocoapods工具管理下显示的;
Workspace Settings 是一般项目中显示的
把new build system(Defalt)切换到 Legacy Build System 在模拟器上运行就OK!
15:Xcode错误: Errors were encountered while preparing your device for development.Please check the Devices and Simulators Window.
解决方案:重启手机
根据Xcode的弹框提示,是真机或者模拟器除了问题。
16:真机运行时报错: does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
这个报错是因为项目中的某个二进制库不支持bitcode,而Xcode默认是要支持bitcode的,而且如果支持的话,其中所有的二进制库和framework都必须包含bitcode。所以要把 Build Settings - Build Options中的Enable Bitcode修改为NO就好了。
其实现在的第三方库大部分是支持bitcode的,只有局部个别老旧的库不支持。