iOS小知识积累(长期更新)

876 阅读5分钟

以前工作中有很多小的知识点,但是有时候只是用了,没有真正积累下来,有时候也会忘记。所以写这篇文章就是慢慢的将以前小的知识点或者之后用到的用文字的形式记录下来。【码字、分享不容易,各位的关注是小的动力!动动亲的小手指关注一下我哈。】
1、_Nullable和_Nonnull(Xcode 6.3 )
_Nullable表示可能是NULL或nil;_Nonnull表示不应该是NULL或nil。如果不遵循会有警告
如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。
2、__kindof(Xcode 6.3 )
表示我们不用强转类型了。比如:

- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;

我们我可以直接用某个cell接收,不用再写(SomeCell*)这种形式强转了。

@property (nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews;

这样,写下面的代码时就没有任何警告了:

UIButton *button = view.subviews.lastObject;

3、instancetype、id、NSObject instancetype 与 id 不一样, instancetype 只能在方法声明中作为返回类型使用。我们写方法返回的时候用instancetype而不用id了。instancetype代表当前类的类型。

  • id关键字在编译时不被检查,而NSObject在编译时会被检查是否被调用一些错误方法。
  • id可以是任何对象,包括非NSObject对象
  • 定义id的时候不使用*,是一个指针,NSObject却需要。

4、Storyboard References (iOS 9)
可以帮我们简化Storyboard,平时我们的做法是将一个大的Storyboard人为的去分成几个小的,然后代码组装起来。Storyboard References可以帮我们简化这一步。如果本身有一个Storyboard很负责,可以选择其中联系很大的一部分,然后点击 Xcode 的菜单栏,选择"Editor->Refactor to Storyboard"。这时候就有一个独立的Storyboard了。
5、打印当前ViewController 的名字
这个对于我们拿到一个陌生的代码,调试的时候非常方便。比如我们运行一个APP,看到一个界面,但是想知道对应哪个ViewController的时候。

  • 添加Symbolic Exception


    A7AB9D87-CF83-4F63-8D66-9C5A113B76ED.png
    A7AB9D87-CF83-4F63-8D66-9C5A113B76ED.png
  • 添加Symob和Action


    73D79C18-5E28-4A87-B039-4DDA566FD5F7.png
    73D79C18-5E28-4A87-B039-4DDA566FD5F7.png

6、Autolayout中Intrinstic Size、Compression Resistance Priority、Compression Resistance Priority

  • Intrinstic Size就是不用设置frame,视图通过内容、字体大小等属性就能获得的大小。我们设置的Content Hugging Priority和Compression Resistance Priority都是针对于这个的。
  • Content Hugging Priority 内容拥抱,就是想变小的优先级
  • Compression Resistance Priority抗压缩,就是想变大的优先级
A90EC537-5342-47B0-8207-9F3DBC0AB8A3.png
A90EC537-5342-47B0-8207-9F3DBC0AB8A3.png

如上图视图内容比文字内容宽,这个时候我们想要视图变小,与文字大小一样(此时intrinsic的大小就是文字区域部分的大小)。所以只要改变Content Hugging Priority的Horizontal的优先级变大就好了
7、topLayoutGuide&& bottomLayoutGuide
这两个属性可以理解为性表示不希望被透明的状态栏或导航栏(UITabBar、UIToolBar、NavigationBar等)遮挡的内容范围的最高或最低位置。这个属性的值是它的length属性的值。如下:

[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(self.mas_topLayoutGuideBottom);
    make.leading.mas_equalTo(self.view.mas_leading);
    make.trailing.mas_equalTo(self.view.mas_trailing);
    make.bottom.mas_equalTo(self.mas_bottomLayoutGuideTop);
}];

8、Autolayout中约束LayoutConstraint的有效无效(8.0) 有时候我们经常遇到一个view在不同的场景下约束不同,通常做法就是在不同场景下先删除再增加这样操作,这样效率反而不高。我们可以通过active这个属性设置生效不生效。

self.mLayoutConstraintWidth.active = YES;

9、隐藏导航栏返回按钮旁边的文字

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];

10、替换返回按钮图片

UIImage *bgImage = [[UIImage imageNamed:@"return"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[[UINavigationBar appearance] setBackIndicatorImage:bgImage];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:bgImage];

11、头文件导入 @class 在.h文件时引入其他.h文件的时候,效率更高

include "" 自己写的文件

include <> 引入系统的

import <> 用于包含系统文件

import ""自己写的文件,搜索路径更广

import比include更好,能够避免文件的重复导入,效率更高
不过还有一个更好的的方式@import,这种方式让我们不必在设置里边添加包了,它会帮我们自动关联。
12、内存管理语义

  • assign "设置方法"只会执行针对"纯量类型"(例如CGFloat或NSInteger等)的简单赋值操作
  • strong 此特质表明该属性定义了一种"拥有关系"。为这种属性设置新值时,设置方法会先保留新值,并释放旧值,然后再将新值设置上去。
  • weak (5.0以上,可以说是对unsafe_unretained的一个升级,更安全,但是由于要遍历是否已经销毁,并且设置成nil,所以是消耗性能)此特质表明该属性定义了一种"非拥有关系"。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似,然而在属性所指的对象遭到摧毁时,属性值也会清空(nil)。
  • unsafe_unretained (5.0以下必须使用而不能使用weak,优点比weak快,缺点容易造成野指针)此特质的语义和assign相同,但是它使用于"对象类型",该特质表达一种"非拥有关系",当对象遭到摧毁时,属性值不会自动清空("不安全",unsafe)这一点与weak有区别。
  • copy 此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其"拷贝"。警惕NSMutableArray为copy的时候奔溃问题。copy之后是NSArray添加对象会crash。
    13、查找或判断xib是否存在
NSString *path = [[NSBundle mainBundle] pathForResource:NSStringFromClass(className) ofType:@"nib"];
Boolean exist = [[NSFileManager defaultManager] fileExistsAtPath:path];

备注:其实关键就是Typ是"nib"而不是"xib"。因为我们打出的包,系统将我们的xib文件编译成了以nib为结尾的文件。
14、UI_APPEARANCE_SELECTOR
当我们自定义控件的时候可以在属性后边增加这个声明。代表支持appearance方法。如果你自己调用了setXX方法,则appearance方法失效。

@property (nonatomic, assign) CGFloat selectionIndicatorHeight UI_APPEARANCE_SELECTOR;
[XXXClass appearance].selectionIndicatorHeight = xxxx

15、旋转动画方向问题

button.transform = CGAffineTransformRotate(button.transform,M_PI);

我们先旋转180顺时针

button.transform = CGAffineTransformIdentity;

当我们调用上句话的时候,是顺时针旋转180返回原位置,但是很多时候我们想原路返回,其实就是想逆时针返回。

button.transform = CGAffineTransformRotate(button.transform,M_PI-0.0001);

只要这么设置就会逆时针返回了。旋转动画选择了最短路径返回