iOS底层探究

IOS中OC的基础语法大杂烩,看这一篇文章就够了

2020-06-30  本文已影响0人  时光啊混蛋_97boy

原创:知识点总结性文章
无私奉献,为国为民,创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容

目录

一、oc语言--面向对象的三大特性

OC语言是C 编程语言的超集,提供面向对象的功能和动态运行时。虽然消息发送同函数调用相比确实慢一点,但却有面向对象的动态绑定、多态等优点。

面向对象的三大特性是面向对象语言的精华所在。面向对象是基于万物皆对象这个哲学观点。抽象化指的是尽可能地不考虑相关细节,只关注对象的核心和本质。类就是舍弃了每个具体对象的各种细节的模版。把一个对象抽象成类,具体上就是把一个对象的静态特征和动态特征抽象成相应的属性和方法,也就是把一类事物的算法和数据结构封装在一个类之中,程序就是多个对象和互相之间的通信组成的。用类创建对象的过程叫作实例化(instantiation ),不同对象之间可以共享该类中的方法,差异就在于具体值的不同。

面向对象具有封装性,继承性,多态性,封装隐蔽了对象内部不需要暴露给外人的细节,使得内部细节的变动跟外界不相关,只单纯依靠提供的接口进行通信。封装性降低了编程的复杂,通过继承,使得新建一个类变得更加容易,一个类从父类那里获得其方法和属性的工作就交给了编译器。而继承、实现和运行时的类型绑定机制所产生的多态,使得不同的类所产生的对象能够对相同的消息作出不同的反应,这极大地提高了代码的通用性。言而总之,面向对象的三大特性大大提高了程序的重用性和可维护性。

1、封装

什么是封装

封装的好处

2、继承

什么是继承:通过继承,子类可以拥有父类中所有的成员变量和方法
重写:子类重新实现父类中某个方法,覆盖父类以前的做法
super:super处在对象方法中,就调用父类的对象方法;super处在类方法中,就调用父类的类方法

作用

使用场合

注意

3、多态

什么是多态:没有继承就没有多态,不同对象对同一消息的不同相应,子类可以重写父类的方法
局限性:父类类型变量不能够直接调用子类特有的方法(编译过程会有警告)。必须强转为子类类型便后后,才能够直接调用子类特有的方法。

二、XCode开发环境

1、视图元素

控件:继承自 UIControl类,能够响应用户高级事件
窗口:应用只有一个UIWindow对象,它是所有子视图的“根"容器
容器视图:UIScrollView的子类有UITextViewUITableViewUICollectionView, 在内容超出屏幕时,它们可以提供水平或垂直滚动条。
显示视图:包括UIImageViewUILabelUIProgressViewUIActivityindicatorView
文本和Web视图:包括UITextviewUIWebView, UIWebView是能够加载和显示 HTML代码的视图
导航视图:包括UITabBarUINavigationBar

2、视图跳转

故事板:本质上是一个XML文件,可以用来描述应用中有哪些界面、界面中有哪些视图元素,它 们的布局、事件处理,以及界面之间是如何导航(或跳转)的
场景 (scene) 和过渡 (segue):一个场景中包含一个视图控 制器,视图控制器通过管理视图来显示界面 ,过渡定义了场景之间的导航(或跳转)方式。

3、Project属性设置

Deployment Target:部署配置,主要是对本project的生成的App的可以运行的最低版本进行配置,默认是当前Xcode上API的最新版本,所以,在我们的项目中有需要对低版本适配的地方需要在这里设置。同样的,我们还可以在build setting中对这一属性进行设置,两者是同步的。

Localizations:本地化,这里的功能主要是添加我们的App所支持的语言,通过上图最下面的红色圈内的【+】【-】按钮可以添加或删除不同的语种,并可以选择根据手机的设置进行不同语种的自适应。关于最下面的选择是否开启国际化,默认是开启的,至于如何进行国际化和不同语种的适配详情见:详述iOS国际化

Configurations:用来配置iOS项目的xcconfig文件,主要用于在几套不同的开发环境编译。Cocoapods的项目配置管理很多都是依赖xcconfig文件去实现的。

4、target属性设置

发布信息:

Identify(标识符)栏:主要定义了一些和应用发布有关的标识属性。
Display Name(App应用显示名):安装到iOS手机或iPad上App的名称。
Bundle Identifier(包标识符):是该应用的唯一ID,用来让操作系统和AppStore识别。在创建项目或者对象过程中Xcode就自行创建了包标识符,一般情况下不要修改它。
Version(外部版本号):使用户能够看到的版本号。
Build(内部版本号):开发者自己看到的版本号,以区分内部测试版本。
Signing(签名):主要是进行证书管理,在真机调试或者打包时我们都需要进行签名进行认证才可以的。

部署信息:

Deployment Target(部署对象):用来设置支持的最低版本。这个和projectinfo中的一个意思,并且,这两个的设置最好是一样,如果不一样,最后的App会以target的设置为准。
Devices(设备):用来设置支持的设备,有iPhone、iPad和Universal三个选项。
Main Interface(主界面):应用启动时预加载的主界面视图。
Device Orientation(设备方向):定义应用支持的方向。有PortraitUpside DownLandscape Left(横评、Home键在左)、Landscape Right几种方向。

App icon Source(应用图标):

Notification:通知时的图标,类似有应用相关的推送消息时,有时候需要显示本应用的图标则会显示这个尺寸的
Spotlight:搜索小图标,当在Spotlight中输入应用名,搜索结果中出现该应用时的图标就是这个尺寸的,还有设置里的图标也是这个尺寸的。
App:这就是正常的App图标,安装好之后在桌面显示的,或者分享推荐时显示的应用也是这个尺寸的图标
App store:应用商店中的显示的图标

Luanch Image Source(启动图片):将所有切好的图标直接拖过来,他们会自动找到自己应该放在的格子里
启动图片实际上定义了应用启动后的界面大小,所以在不同机型中我们需要做好适配,一款App必须设定对应设备的启动图片,否则点开应用会是一片黑白。
Luanch Screen File(启动页面文件):storyboard文件,作用与Luanch Image一样,但是启动文件的优先级高于启动图片,就是说如果两个都设置了,那么启动页面以启动文件为准,如果都没有设置,则无法启动。

Embedded Binaries(绑定二进制文件):用来连接二进制文件,一般在使用第三方SDK的时候使用。
Linked Frameworks and Libraries(链接的框架和库):既可以是SDK自带的框架,也可以是第三方框架,在Build Phases中也有类似的功能选项。

5、info属性设置

项目资源目录下的info.plist文件中的内容是一致,并且修改其中一个另一个会自动修改。
Localization native development region : 与本地化设置有关,为默认的开发语言
Executable file:程序安装包的名称
Bundle identifier:软件唯一的标识,是根据公司的标识与项目名称自动生成的,在上传和测试的时候会用到
InfoDictionary version:版本信息
Bundle name:App安装后显示的名称
Bundle OS Type code:用来标识软件包类型
Bundle versions string, short:发布的版本字符串
Bundle creator OS Type code:创建者的标识
Bundle version:应用程序版本号
Application requires iPhone environment:用于指示程序包是否只能运行在iPhone OS 系统上,默认为YES
Launch screen interface file base name:欢迎界面的文件名称
Main storyboard file base name:默认情况下程序的主入口
Supported interface orientations:设置程序默认支持的方向

常用权限设置:

麦克风权限:Privacy - Microphone Usage Description 是否允许使用你的麦克风?
相机权限: Privacy - Camera Usage Description 是否允许使用你的相机?
相册权限: Privacy - Photo Library Usage Description 是否允许访问你的媒体资料库?
通讯录权限: Privacy - Contacts Usage Description 是否允许访问你的通讯录?
蓝牙权限:Privacy - Bluetooth Peripheral Usage Description 是否许允使用蓝牙?
语音转文字权限:Privacy - Speech Recognition Usage Description 是否允许使用语音识别?
日历权限:Privacy - Calendars Usage Description 是否允许使用日历?
定位权限:Privacy - Location When In Use Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据
定位权限:Privacy - Location Always Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据

6、capabilities属性设置

性能设置开关选择,例如推送通知、云存储、游戏中心、后台模式等。
info.plist添加一些权限或性能开关之后,在targetcapabilities中也会进行相应的修改的。

7、Resource Tag属性设置

Resource Tag选项卡主要是为项目中的资源进行添加tag分类,方便我们对齐加载顺序和加载时机进行选择和设置,即实现在需要的时候才加载资源。

初始资源的延迟加载:app有一些资源是主要功能要用到的,但在启动时并不需要。将这些资源标记为“初始需要”。操作系统在app启动时会自动下载这些资源。例如,图片编辑app有许多不常用的滤镜。

app资源的延迟加载:app有一些只在特定情景下使用的资源,当应用可能要进入这些场景时,会请求这些资源。例如,在一个有很多关卡的游戏中,用户只需要当前关卡和下一关卡的资源。

不常用资源的远程存储:app有一些很少使用的资源,当需要这些资源时会去请求它们。例如,当app第一次打开时会展示一个教程,而这个教程之后就可能不会在用到。app在第一次启动时请求教程的资源,这之后只在需要展示教程或者添加了新功能才去请求该资源。

应用内购买资源的远程存储:app提供包含额外资源的应用内购买。app会在启动完成后请求已购买模块的资源。例如,用户在一个键盘app内购买了SuperGeeky表情包。应用程序会在启动完成后请求表情包的资源。

第一次启动时必需资源的加载:app有一些资源只在第一次启动时需要,之后的启动不再需要。例如,app有一个只在第一次启动时展示的教程。

8、build setting属性设置

Resolved列:最终确定的编译方式,无法自己设定,其结果是根据其右边三栏的选择结果以及优先级顺序来确定最后编译时采用的编译方式。在图的第二行选项卡中选择combined选项,可以直接地看到只有该栏的最后结果。

带Target图标列:targetbuild setting配置的编译选项,可自定义。其优先级最高,一旦进行设置,则最后的编译方式以该栏的结果为准。

带Project图标列:projectbuild setting配置的编译选项,可自定义,这一栏的结果与projectbuild setting选项卡中的结果是一致的,修改其中一个地方,另一处也会自动修改。其优先级介于targetdefault之间,当target没有设置编译选项,而该栏进行了设置时,则最后的编译方式以该栏为准。

iOS Default列:在创建项目时系统自带的默认编译选项,无法修改。优先级最低,只有当其他两栏都没有设置选项时,最后的编译方式才会以该栏为准。

优先级顺序:Target图标列 >> 带Project图标列 >> iOS Default

9、build phase属性设置

配置编译器在不同编译阶段的参数,包括编译所需的资源文件(包括代码、配置以及各种资源文件)

Target Dependencies Target 对象依赖阶段:某些Target可能依赖某个Target输出的值,这里设置依赖。依赖于其他target的输出的时候,在编译时系统会自动先编译被依赖的target,得到输出值,再编译当前target。(比如应用扩展、插件等等),这个阶段是无法被删除的。

Compile Sources 源文件编译阶段: 是指将有哪些源代码被编译,可以通过红框中的【+】【-】按钮进行添加或删除资源来控制编译的代码文件。并且可以通过修改改阶段的Compiler Flags(编译器标识)来为每个单独文件设置其编译器标识,比如优化设置等等。

Link Binary With Libraries 链接二进制库阶段:是指编译过程中会引用哪些库文件,我们同样可以通过【+】【-】按钮进行添加或删除编译所引用的库文件。

Copy Bundle Resources 复制资源文件阶段:是指生成的product.app内将包含哪些资源文件,同样可以通过红框中的【+】【-】按钮进行添加或删除资源来控制编译的资源文件。该阶段定义了对象中的资源文件,包括应用程序、图标、界面构造器、视频、模板等等。这些资源都会被复制到安装包的Contents/Resources文件夹下。

10、设置应用图标和启动图片

一来通过启动图片设定了我们App应用在本次启动时以多大的界面进行展示信息,如果不设置启动界面,我们的App在打开后后会出现黑屏的显影导致应用无法正常使用。如果启动图片是iPhone6的屏幕大小的图片,则在iPhone X上只显示iPhone6的屏幕大小区域,上下会有两条黑边。因此,我们再设定启动界面的时候一般是需要适配各种屏幕大小尺寸的启动图片。如下图所示的界面可以看到设置Luanch Image Source(启动图片)是有多种尺寸的。

二来则是在我们点击应用图标启动应用时,应用启动需要一定的操作时间,在启动期间,为了增强应用程序启动时的用户体验,您应该提供一个启动图像。启动图像与应用程序的首屏幕看起来非常相似。当用户在主屏幕上点击您的应用程序图标时,iPhone OS会立即显示这个启动图像。一旦准备就绪,您的应用程序就会显示它的首屏幕,来替换掉这个启动占位图像。一定要强调的是,之所以提供启动图像,是为了改善用户体验,并不是为了提供:应用程序进入体验」,比如启动动画。

Luanch Image Source(启动图片):同样对应着文件资源Assets.xcassets目录中的LuanchImage中的图片,设定了各种情况下的启动图片,具体界面如上图所示,和Appicon一样,我们将所有切好的图标直接拖过来,他们会自动找到自己应该放在的格子里,同样可以选择设备以及不同方向的启动图。

Luanch Screen File(启动页面文件):是通过一个LuanchScreen.storyboard文件来作为启动界面。

两种方法之间主要的区别在于启动文件的优先级高于启动图片,也就是说如果两个都设置了,那么启动页面以启动文件为准,如果都没有设置,则应用会黑屏。

由于启动文件的优先级高于启动图片,所以我们需要将启动文件后的文件名删去,此外我们还需要将项目中的LuanchScreen.storyboard文件也给删去,这是因为App在启动时系统会自动查找LuanchScreen.storyboard的文件进行加载。

三、UIKit框架的使用

视图分类

控件:UIControl事件
窗口:UIWindow 根容器
容器视图:UIScrollView(及其子视图)、UIToolbar
显示视图:UIImageViewUILabelUIProgressViewUIActivity
文本和Web视图:UITextViewUIWebView
导航视图:UITabBarUINavigationBar
警告框和操作表:UIAlertController

事件传递&视图响应

UIView CALayer(单一执行原则):UIView 为其提供内容以及负责处理触摸等事件,参与响应链
CALayer负责显示内容contents

视图传递流程:

视图传递流程

视图响应流程:

视图响应流程

属性声明:

 @property (nonatomic, strong, readonly) UILabel *title;
 @property (nonatomic, strong) UIPickerView *pickerView;
 @property (nonatomic, strong) UIDatePicker *datePicker;
 @property (nonatomic, strong) UIScrollView *scrollView;
 @property (nonatomic, strong) UIPageControl *pageControl;

UIView

UIWindow

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];

UIView

- (void)setNeedsLayout;
- (void)layoutIfNeeded;
- (void)layoutSubviews;
- (void)removeFromSuperview;
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;

self.view.subviews
[self.view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];

CALayer

CALayer  *layer;
layer.borderWidth
layer.borderColor

UISlider

slider.value
horizontalSlider.minimumValue = 10;
horizontalSlider.maximumValue = 100;
[horizontalSlider addTarget:self action:@selector(horizontalSliderChanged:) forControlEvents:UIControlEventValueChanged];

UISegmentedControl

segmentControl.selectedSegmentIndex = 1;

UISwitch

// 切换明文/密文时,需要去掉光标空白部分
- (void)secureSwitchAction:(UISwitch *)sender {
    //切换
    self.passwordTextField.secureTextEntry = !self.passwordTextField.secureTextEntry;
    //
    NSString* text = self.passwordTextField.text;
    self.passwordTextField.text = @" ";
    self.passwordTextField.text = text;
}

UIActivityIndicatorView

// 是否在旋转
self.activityIndicatorView.isAnimating

// 非活动状态时,控件会隐藏 
Hides When Stopped

UIProgressView

self.progressView.progress = self.progressView.progress + 0.1;
if (self.progressView.progress == 1.0) {
    [self.timer invalidate];
}

UIRefreshControl

self.collectionView.alwaysBounceVertical = YES;// 必须打开
self.refreshControl.tintColor = [UIColor grayColor];
[self.refreshControl addTarget:self action:@selector(urlRequestForCollection) forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:self.refreshControl];
[weakSelf.refreshControl endRefreshing];// 结束刷新

UIPageController

    self.pageControl = [[UIPageControl alloc] init];
    self.pageControl.numberOfPages = 3;
    self.pageControl.pageIndicatorTintColor = [UIColor colorWithWhite:1 alpha:0.5];
    self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];

UIScrollView

    self.scrollView.pagingEnabled = YES;
    self.scrollView.showsVerticalScrollIndicator = FALSE;
    self.scrollView.showsHorizontalScrollIndicator = FALSE;
    self.scrollView.minimumZoomScale = 0.5;
    self.scrollView.maximumZoomScale = 2.0;
    self.scrollView.contentSize = CGSizeMake(WIDTH * 3, HEIGHT);//内容3倍横向滑动
    self.scrollView.frame = self.view.frame;//正是因为内容视图超出了屏器滚动视图的大小,才有滚动屏幕的必要 
    self.scrollView.contentOffset = CGPointMake(S_WIDTH * whichPage, 0.0f);

UITableView

// 设置为0不起作用
heightForHeaderInSection:  return 0.1;

// 不显示右侧滑块
showsVerticalScrollIndicator = NO;  

// 分割线
separatorStyle = UITableViewCellSeparatorStyleSingleLine;

// 选中风格
cell.selectionStyle = UITableViewCellSelectionStyleNone;

// cell可以设置装饰图
cell.accessoryView = imageBtn;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;//右指示器
accessoryButtonTappedForRowWithIndexPath://方法

// cell自带imageView属性、text属性、detailTextLabel属性
cell.detailTextLabel.text = @"更多";
cell.detailTextLabel.userInteractionEnabled = YES;
cell.detailTextLabel.backgroundColor = [UIColor blackColor];

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(moreInformation:)];
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 1;
[cell.detailTextLabel addGestureRecognizer:tap];

// 表头表尾高度
self.tableView.sectionHeaderHeight = 0.1;
self.tableView.sectionFooterHeight = 20;

// 弹动
self.tableView.bounces = NO;

// 能否编辑某行
canEditRowAtIndexPath:return YES;

// cell初始化
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
        cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    }
    cell.textLabel.text = self.vcTitles[indexPath.row];
// 选中cell
    switch (indexPath.row) {
        case 0:
        {
            UCARSubviewViewController *vc = [[UCARSubviewViewController alloc] init];
            [self.navigationController pushViewController:vc animated:YES];
            break;
        }
        default:
            break;

UICollectionView

// 集合视图布局
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(90, 130);
layout.sectionInset = UIEdgeInsetsMake(15, 15, 20, 20);//内边距
layout.minimumLineSpacing = 5;//单元格之间的间距
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];

UITextField

// viewWillDisappear中调用,因为跳转页面时,警告框或者键盘不能再出现
[self.view endEditing:YES];

// 显示清空按钮
self.phoneNumberTextField.clearButtonMode = UITextFieldViewModeWhileEditing;

// 点击清除按钮,应该将之前的文本清空
- (BOOL)textFieldShouldClear:(UITextField *)textField {
    if (textField == self.loginView.phoneNumberTextField ) {
        self.phoneNumber = @"";
    }
    if (self.loginView.passwordTextField == textField) {
        self.password = @"";
    }
    return YES;
}

// 去掉空格
NSString *phone = [textField.text stringByReplacingCharactersInRange:range withString:string];
self.phoneNumber = [phone stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];   

// 边框样式
self.searchTextField.borderStyle = UITextBorderStyleRoundedRect;

// 左视图
self.searchTextField.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"commodity_searchCommodityViewController_search"]];
self.searchTextField.leftViewMode = UITextFieldViewModeAlways;

// 及时捕获文本框的值
- (NSString *)text {
    _text = self.searchTextField.text;
    return _text;
}

// 返回类型
self.searchTextField.returnKeyType = UIReturnKeySearch;

UIViewController

生命周期

alloc 创建对象,分配空间
init (initWithNibName) 初始化对象,初始化数据
initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)
loadView:加载view
viewDidLoad 载入完成,只会在APP刚开始加载的时候调用一次,所以只能用来做初始设置
viewWillAppear 需要对数据做更新
viewDidAppear 视图已在屏幕上渲染完成
viewWillDisappear 被移除覆盖时进行善后的处理,按了Home键之后,APP本身仍是挂起时候的view,不调用
viewDidDisappear 对已经消失、覆盖、隐藏了的视图做一些其他操作
dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放
viewWillLayoutSubviews多次调用布局
viewDidLayoutSubviews

UINavigationController

navigationItem.rightBarButtonItems = @[dismissVCItem, popVCItem];// 数组

// 配置导航栏
- (void)configureNavigationbar {
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"rightItem" style:UIBarButtonItemStylePlain target:self action:@selector(rightBarItemAction)];
}

UITabBarController

// push到下个界面隐藏底部TabBar
loginViewController.hidesBottomBarWhenPushed = YES;

// 获取当前选中的item
selectedItem

// badge的数值
tabBarItem.badgeValue = @"10";

// Tab标签栏跳转,比如从用户中心跳转到首页:
[self.navigationController popViewControllerAnimated:NO];
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
UITabBarController *tab = (UITabBarController *)delegate.window.rootViewController;
tab.selectedIndex = 0;

// 数组
self.viewControllers = @[redVC, blueVC];

四、Foundation框架的使用

属性声明:

//默认关键字
@property (atomic, strong, readwrite) NSString *firstName;

@property (readonly, getter=isShit) BOOL shit;

@property (nonatomic, strong) NSArray *vcTitles;
@property (nonatomic, strong) NSArray<NSArray *> *pickerData;


@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) personBlock runFinishBlock;

@property (nonatomic, weak) id<WorkProtocol> delegate;
@property (nonatomic, weak) id<CountToolDataSource> dataSource;

@property (nonatomic, assign) int age;
@property (nonatomic, assign) BOOL bodyTextChanged;
@property (nonatomic, assign) NSTimeInterval created;

缩写:
f: function 函数
p: parameter 参数
m:method 方法
c: class
v: variable 变量

属性关键字:
atomic:系统默认,声明的属性保证赋值和获取是线程安全的,不保证添加和移除是线程安全的(如数组)
noatomic:经常声明
retain/strong
assign/unsafe_unretained:修饰基本数据类型,如int、Bool。修饰对象类型时候,不改变其引用计数。对象释放后,会产生悬垂指针,仍访问会产生内存泄露。
weak:不改变修饰对象的引用计数,对象释放后,自动置为nil
copy浅拷贝和深拷贝的区别:是否开辟了新的内存空间,是否影响了引用计数。可变对象copy 后是NSArray 不可以调用add delete等方法。只有不可变对象的copy是浅拷贝,其他都是深拷贝。

1、基本数据类型

NSObject

NSObject *boolObj = [[NSObject alloc] init];
if (boolObj) {
    NSLog(@"not nil = YES");
}

//描述信息
[Person description]

 //包含关系
 BOOL isKind = [aPerson isKindOfClass:[Person class]];
 BOOL isKindObj = [aPerson isKindOfClass:[NSObject class]];
 BOOL isMemeber = [admin isMemberOfClass:[Administrator class]];

Struct

typedef struct {
    int I;
    float f;
} MyIntegerFloatStruct;
//NSRange/CGRect/CGSize/CGPoint:本质为struct
NSRange dRange = NSMakeRange(1, 2);
枚举
typedef NS_ENUM(NSInteger, NumberType) {
     NumberTypeInt = 0,
     NumberTypeFloat = 1,
     NumberTypeDouble = 2
};
NumberType type = NumberTypeInt;



typedef NS_OPTIONS(NSUInteger, TMEnumTest)
{
    TMEnumTestOne     = 0,          // 0
    TMEnumTestTwo     = 1 << 0,     // 1
    TMEnumTestThree   = 1 << 1,     // 2
    TMEnumTestFour    = 1 << 2,     // 4
};
// 基本用不到下面的语法,一般不用管

TMEnumTest test = TMEnumTestTwo  |  TMEnumTestThree;  // 3
// 添加TMEnumTestFour到test中
test += TMEnumTestFour
// 将TMEnumTestThree从test中去除
test -= TMEnumTestThree
// 判断 TMEnumTestFour枚举 是否被包含
if (test & TMEnumTestFour)



typedef NS_OPTIONS(NSUInteger, LifeRoleOptions) {
    LifeRoleOptionsFather =   1UL << 0,
    LifeRoleOptionsSon = 1UL << 1,
    LifeRoleOptionsHusband = 1UL << 3,
};

//基本用不到下面的语法,一般不用管
LifeRoleOptions lifeRole = LifeRoleOptionsFather | LifeRoleOptionsSon;
        if (lifeRole & LifeRoleOptionsFather) {
            NSLog(@"father");
        }
        
        if (lifeRole & LifeRoleOptionsHusband) {
            NSLog(@"husband");
        }
NSNumber
static int globalCount = 0;

NSInteger aInt = -1;
NSUInteger bUInt = 1;

// 用语法糖进行声明,可转换为多种数据类型
NSNumber *intNumber = @(-1);
NSNumber *boolNumber = @(YES);//1
NSNumber *charNumber = @('A');//65
NSLog(@"int %@ bool %@ char %@", intNumber, boolNumber, charNumber);
NSLog(@"char %d str %@ int %d", charNumber.charValue, charNumber.stringValue, charNumber.intValue);//65
BOOL
BOOL hidden = YES;
BOOL bigger = 0 > 1;
CGFloat
CGFloat cFloat = 0.0f;
NSData
dataWithContentsOfFile //从参数path 指定的文件读入二进制数据,用该数据初始化NSData 对象
writeToFile //将接收者的二进制数据写入path 指定的文件中

NSString *dataString = @"abc";
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];//<616263>

NSData *zeroData = [NSData data];//<>
NSMutableData *appendData = [zeroData mutableCopy];
[appendData appendData:data];//<616263>
NSString
//字符串对象内部使用Unicode 编码
UTF8String //返回C语言字符串的指针
initWithData //用存储在data中的二进制数据来初始化NSString 对象
caseInsensitiveCompare //不区分大小写
localizedStandardCompare //本地化
substringTo(from)Index //截取
subtringWithRange //范围
lowercaseString //小写
uppercaseString //大写
capitalizedString //首字母变为大写
floatValue 、intValue 、integerValue 、boolValue //分别被用来把NSString 类型的字符串转为float 、int、NSinteger 和BOOL 类型的数值
lastPathComponent //以文件路径名@"/tmp/image/cat.tiff' 为例,返回"cat.tiff'
pathExtension //返回文件的扩展
 StringW ithContentsOfFile //通过读取文件path 中的内容来初始化一个NSString

NSString *copyChineseString = [chineseString copy];
NSString *pureChineseString = [chineseString stringByReplacingOccurrencesOfString:@"哈" withString:@""];//replace(删除)

NSComparisonResult abcOrder = [abc compare:aBc];// compare
BOOL hasSuffix = [aBc hasSuffix:@"Bc"];// hasSuffix

NSString *homePath = NSHomeDirectory();// 能够访回当前用户的主目录
NSString *workPath = [homePath stringByAppendingPathComponent:@"*work"]; //将" . "和指定的扩展名添加到现有路径的最后一个组成部分
NSArray *pathArray = [homePath componentsSeparatedByString:@"/"];//str to array

NSMutableString *testStr = [[NSMutableString alloc] initWithString:@"我知道什么呢?"];
[testStr appendString:@"什么都知道"];
 //随着字符串的变化而自动扩展内存,所以capacity 不需要非常精密
 NSMutableString* mutableString = [[NSMutableString alloc] initWithCapacity:20];
 //在尾部添加,返回void,不产生新字符串
 [mutableString appendString:@"hello"];
 //尾部添加格式化字符串
 [mutableString appendFormat:@"hello%i",100];
 //插入字符串
 [mutableString insertString:@"你好" atIndex:5];
 //替换
 [mutableString replaceCharactersInRange:range withString:@"大家好"];
 //分割
 NSArray *newArray = [str componentsSeparatedByString:@","];
 //拼接
 NSString *newStr = [array componentsJoinedByString:@","];

NSAttributedString *singleLineTextAttr = [[NSAttributedString alloc] initWithString:singleLineText attributes:@{NSUnderlineStyleAttributeName: @(1)}];
singleLineLabel.attributedText = singleLineTextAttr;
nil
//默认值: NO/0/nil
Person *aPerson = nil;
aPerson.age //0
NSNull
+ (NSNull *) null //不能在数组和词典对象中放入nil ,又确实需要一个特殊的对象来表示空值

NSArray

// 初始化
NSArray *columnFirst = @[@"row0",@"row1",@"row2",@"row3",@"row4"];
self.pickerData = @[columnFirst, columnFirst];

NSArray *aArray = @[@1, @2, @3];
NSArray *cArray = [NSArray arrayWithObjects:@1, @"2", nil, @3, bPerson, nil];
NSArray<NSString *> *numArray = @[@"2", @"4", @"3", @"1"];
NSArray<NSNumber *> *numArray = @[@0, @(0+1), @(1+1)];

Person *aPerson = [Person new];
_allPersons = @[aPerson, bPerson];

//取值
NSString *index1InbArray = [bArray objectAtIndex:1];
NSNumber *index0InbArray = bArray[0];

// 遍历器 
// 遍历方式:for循环、NSEnumerator、for in
// enumerateObjectsUsingBlock:通过block回调,在子线程中遍历,对象的回调次序是乱序的,而且调用线程会等待该遍历过程完成
//这几个for in性能最好,for循环较低, 多线程遍历方式是性能最差的
NSEnumerator *enumerator = [array objectEnumerator];
for(id object = [enumerator nextObject]) {}

// 排序
NSArray *newArray = [array sortedArrayUsingSelector:@selector(compare:)];

//过滤
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", @"[2-9]+"];
NSArray *filteredArray = [numArray filteredArrayUsingPredicate:predicate];

//可变
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:numArray];
[mutableArray replaceObjectAtIndex:0 withObject:@"0"];

//浅拷贝
NSArray *shallowCopyArray = [bArray copy];(shallowCopyArray == bArray)(shallowCopyArray[3] == bArray[3])
NSDictionary
NSDictionary *aDict = @{@"key": @"2", @"3": @"4", @4: @5, bPerson: @""}; //error,person不遵循copying协议
NSDictionary *bDict = @{@"key": @"2", @"3": nil}; //error,can't store nil,推荐使用语法糖初始化,常规方式遇nil可能截断,语法糖则会报错
NSDictionary<NSString *, NSString *> *strDict = @{@"1": @"a", @"2": @"b"};

// 可变
[mutableDictionary removeObjectForKey:bArray];
mutableDictionary[@"newKey"] = @"newKey";
NSSet
//初始化
NSSet *aSet = [NSSet setWithObjects:@1, bPerson, nil];
//if deep copy, all elements must conform NSCopying
NSSet *deepCopySet = [[NSSet alloc] initWithSet:aSet copyItems:YES];
NSDate
// NSString转NSDate
- (NSDate *)dateFromString:(NSString *)dateString
{
    //设置转换格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    //NSString转NSDate
    NSDate *date=[formatter dateFromString:dateString];
    return date;
}

NSComparisonResult

//字符串比较大小
NSComparisonResult result = [str1 compare:str2];
if(result == NSOrderedSame) {
   NSLog(@"str1 == str2");
} else if(result == NSOrderedAscending) {
   NSLog(@"str1 < str2");
}

// 自定义比较方法
- [(NSComparisonResult)compareWithAge:(Person *)p {
        if(_age == p.age) {
            return NSOrderedSame;
        }else if(_age > p.age) {
            return NSOrderedDescending;
       }
}
get/set
//自定义get
- (NSString *)fullName {
    if (self.firstName && self.lastName) {
        return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
    }
    return nil;
}
 
[self fullName];//调用get
aPerson.objCopy = testStr;//调用set
[aPerson setObjCopy:testStr];//调用set
present模式(present/dismiss)/ navi模式(push/pop)
[self.navigationController presentViewController:presentNavi animated:YES completion:nil]; 
[self dismissViewControllerAnimated:YES completion:nil]; 

[self.navigationController pushViewController:layoutVC animated:YES];// 压入页面为栈顶显示
[self.navigationController popViewControllerAnimated:YES];// 能退到栈中任意位置,其上的页面全部丢弃
扩展(category)
#import "Person.h"
.h
    @interface Person(Worker)
    - (void)printWorkerID;
    @end
.m
    #import "Person+Worker.h"
    @implementation Person(Worker)
默认值初始化
- (instancetype)init {
    self = [super init];
    if (self) {
        _firstName = @"zili";
        _lastName = @"kou";
        _privateName = @"linux";
    }
    return self;
}
重载系统方法
- (instancetype)copyWithZone:(NSZone *)zone {
    Person *p = [[Person alloc] init];
    p.firstName = self.firstName;
    p.lastName = self.lastName;
    return p;
}

五、知识点大杂烩

集合
区别
布局

Auto Layout解决布局问题,而 SizeClass解决屏幕适配问题。

self.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
上一篇 下一篇

猜你喜欢

热点阅读