1、Block导致的循环引用
去除一方强引用即可
2、Block引起的循环引用误报
查看Marsony源码
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
block(constraintMaker);
return [constraintMaker install];
}
self并没有持有block,不会构成引用循环,这是Xcode9.3之后的误报。同样还有这种情况的有遍历的block;GCG的block、UIView animationBlock;
解决方案
2.1、将下划线形式_的实例变量变成点语法
// make.left.mas_greaterThanOrEqualTo(_circleNameLabel.mas_right);
make.left.mas_greaterThanOrEqualTo(self.circleNameLabel.mas_right);
2.2、将这种类型的报警去除
3、不带参数的Block
Xcode 9之后如果定义一个不带参数的block,会有Warning
Warning:This block declaration is not a prototype
解决方案
3.1、加一个void参数
3.2、全部忽略
4、未被使用的变量
Unused variable ‘xxxx’
减少此类Warning有利于节省内存
5、指针未添加nullable标识
Warning:Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)
其实这是由于Swift的加入引起的问题:
我们都知道在swift中,可以使用!和?来表示一个对象是optional的还是non-optional,如view?和view!。而在Objective-C中则没有这一区分,view即可表示这个对象是optional,也可表示是non-optioanl。这样就会造成一个问题:在Swift与Objective-C混编时,Swift编译器并不知道一个Objective-C对象到底是optional还是non-optional,因此这种情况下编译器会隐式地将Objective-C的对象当成是non-optional。
解决方案
NS_ASSUME_NONNULL_BEGIN
//代码
NS_ASSUME_NONNULL_END
6、通过Category来重写原类方法
Warning:Category is implementing a method which will also be implemented by its primary class
苹果的官方文档有写明
If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime。
如果通过Category来重写原类方法可能造成调用方法的不可预知性。
解决方案
6.1、如果是自定义类,用继承的方式父类方法;
6.2、非自定义类,用runtime的method swizzling来进行方法交换处理。
7、未定义方法
Warning:Method definition for ‘showEmptyRolesView:’ not found
如果在父类.h里声明某个方法,只在子类里重写实现,就会有这个Warning。应该在父类里也有一份实现,防止在使用父类时误用这个方法
8、精度缺失
implicit conversion loses integer precision ‘nsinteger’ (aka ‘long’) to ‘int’
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
在不同机器上,定义不一样,官方API是推荐使用NSInteger而不是int/long
9、新的API
Warning:’UIScrollViewContentInsetAdjustmentNever’ is only available on iOS 11.0 or newer
加一个判断
if (@available(iOS 11.0, *)){}
else{}
10、库支持的版本过高
warning: object file …Classes/ProtocolBuffer/Libs/libprotobuff.a(java_message_field.o)) was built for newer iOS version (9.1) than being linked (8.0)
引用文件支持的最低版本比项目编译版本高
解决方案
10.1、重新编译库与项目编译版本匹配
10.2、Build Settions Other links Flags 中添加-w忽略掉
二、通过Clang来忽略警告
1、忽略一段代码的警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wimplicit-retain-self"
// 要忽略警告的代码
#pragma clang diagnostic pop
常用的忽略警告类型
字段 | 警告类型 |
---|---|
-Wimplicit-retain-self | 循环引用 |
-Wstrict-prototypes | 不带参数的block |
-Wshorten-64-to-32 | 精度缺失 |
-Wnullability-completeness | 未添加nullable标识 |
-Wobjc-protocol-method-implementation | Category重写原类方法 |
-Wdeprecated-implementations | 方法被弃用 |
-Wdeprecated-declarations | 字段被弃用 |
-W-documentation | 注释有问题 |
-Wundeclared-selector | 未定义方法 |
-Wincompatible-pointer-types | 对象的指针类型不正确 |
2、忽略整个工程的警告类型
要修改一下“-Wimplicit-retain-self”换成“-Wno-implicit-retain-self”
3、忽略几个文件的警告:
可以在pch等具有大范围作用域的头文件中包含: #pragma clang diagnostic ignored “警告名称” 如果剔除了push与pop则后面所有的代码都具有强制消除警告作用