iOS编程读书笔记

这篇博客详细介绍了iOS编程的基础,从创建第一个简单的iOS应用开始,涵盖了模型-视图-控制器(MVC)概念,Objective-C的使用,包括对象、消息发送,以及内存管理中的ARC。同时,讲解了视图与视图控制器的创建、视图层次结构,以及如何通过Auto Layout进行界面布局。此外,还探讨了视图控制器的生命周期、委托和文本输入,以及数据持久化和Web服务的使用。
摘要由CSDN通过智能技术生成

11,22,23,24,25,28暂时不需要看

1 第一个简单的iOS应用

  • 单击按钮可以改变文字。

1.1 创建Xcode项目

  • 创建项目的时候Xcode会提供一些包含通用代码的模版,可以根据需要选择模版。
  • 创建项目是需要填写Organization Name和Company Identifier,也可以填入自己的公司名称和公司的反向域名。
  • Class Prefix在Xcode 7.2创建项目里面已经没有了,或许是因为默认创建的项目类太少,但是自己在创建类的时候还是加上前缀为好,因为OC没有命名空间。
  • 工作控件左侧是导航面板区域,中间是编辑区域。

1.2 模型-视图-控制器

  • 简单介绍了MVC,下图清晰阐述了MVC中各模块扮演的角色。

1.6

1.3 设计Quiz

  • 使用MVC思想,设计一个名叫Quiz的程序,实现单击按钮改变文字。
  • 下面的应用对象图,勾勒出了对象之间的相互关系。

1.7

1.4 创建视图控制器

  • 新版本Xcode会自动创建ViewController类了,且用storyboard文件来管理视图。
  • storyboard是多个xib文件集合的描述文件,也采用xml格式。那么storyboard与xib比较,区别在于:

    • 一个工程中可以有多个xib文件,一个xib文件对应着一个视图控制器和多个视图。而使用storyboard时,一个工程只需要一个主storyboard文件就可以了。
    • 在包含多个视图控制器的情况下,采用storyboard管理比较方便,而且storyboard还可以描述界面之间的导航关系。
  • Interface Builder一些介绍:

1.5 创建界面

  • 单击main.storyboard编辑视图,画布中间的视图比较宽,可以在右侧属性面板将Use Auto Layout勾选掉。
  • 通过Interface Builder在main.storyboard中添加Button和Label。
    • 构建项目时main.storyboard会被编译为NIB文件,然后Xcode会将NIB文件拷贝到应用程序包(bundle)中,其实就是应用程序以.app结尾的后缀。
    • 应用程序运行时会从程序包中按需载入NIB文件并激活文件中的对象。

1.6 创建关联

  • 通过connection,一个对象可以知道另一个对象在内存中的位置,从而使这两个对象可以协同工作。
  • Interface Builder中的两种关联:
    • outlets:指向对象的指针变量。
    • actions:动作方法,在视图对象和用户发生交互时会被调用。
  • 新版本Xcode创建项目使用storyboard所以没有File's Owner,可以通过打开Assistant editor方便的关联对象:

1.7.1

  • 创建关联在main.storyboard中的体现如下:

1.7.2

1.7 创建模型

  • ViewController对象创建完毕后会收到消息:initWithNibName:bundle:,所以可以在这里进行一些数据创建和初始化。

    • 不一定非得在initWithNibName中初始化数据,新版本Xcode创建的默认项目,使用initWithNibName不会有效果,可以使用initWithCoder
    • initWithNibName和initWithCoder的区别
  • 关于代码自动补全功能:

    • 要实现模糊匹配可以安装FuzzyAutocomplete插件。
    • 自动补全后会有一些占位符,如果要使用占位符,可以按回车即可。

1.8 其它

  • AppDelegate应用程序委托是每个iOS应用都必须具备的启动入口。
  • 新版本Xcode不需要在委托中添加代码,如果按照书中添加代码,会出现白屏。
  • 模拟器中选择Simulator|Reset Content and Settings...可以将模拟器还原到默认设置并删除所有应用。

2 Objective-C

  • 开发iOS应用使用Objective-C和Cocoa Touch框架.

2.1 对象

  • Objective-C语言中,实例变量的变量名之前通常会加一个下划线,如_name,_date,_budget。
  • 调用某个对象的方法,可以向对象发送相应的消息(message)。

2.2 使用对象

  • 创建变量并进行初始化:Party *partyInstance = [[Party alloc] init];,将多个消息合并在一行的写法叫做嵌套消息发送(nested message send)。
  • 消息发送代码各组成部分:

2.2

  • 在Objective-C中,方法的唯一性取决于方法名,即使参数类型和返回类型不同,一个类也不能有两个名称相同的方法。

2.3 编写命令行工具PandomItems

  • 不能在快速枚举for in中添加或删除对象,否则抛出异常。
  • Objective-C格式字符串基本和C语言相同,%@对应的实参类型是指向任何一种对象的指针,通过覆盖description方法定义格式化输出。

2.4 创建Objective-C类的子类

  • Objective-C只允许单继承,所有的类都只能有一个父类。
  • Objective-C保留了C语言的关键字,并增加了特有的关键字,新的关键字都用前缀@加以区分。
  • Objective-C类中的存取方法名的规范为:
    • 存方法命名规则为英文单词set加上要修改的实例变量名,以_itemName为例,存方法名为setItemName:
    • 取方法名就是实例变量的变量名itemName,其它语言大多为:getItemName
  • #import#include的差别在于,#import可以确保不会重复导入同一个文件。
  • 使用点语法存取变量例如item.itemName编译后和发消息一样,也是调用之前写好的存取方法,所以存取方法名要按照规范书写。Apple官方代码坚持使用点语法存取实例变量。
  • 实例方法和类方法:调用实例方法时,需要向类的对象发送消息;调用类方法时,则向类自身发送消息。
  • 使用存取方法访问实例变量是良好的编程习惯,即使是访问对象自身的实例变量,也应该使用存取方法,但是在初始化方法中例外。

  • 初始化方法

    • 每个初始化方法以英文单词init开头,Objective-C中命名约定很重要,应该严格遵守。
    • 初始化方法的返回类型是instancetype,该关键字表示方法的返回类型和调用方法的对象类型相同。
    • instancetype引入之前,初始化方法返回类型是id,表示指向任意对象的指针,类似C语言的void*
  • instancetypeid
    • instancetype只能用来表示方法返回类型,id可以用来表示变量和方法参数类型。
    • id的定义是指向任意对象的指针,所以不需要再加*,比如:id item
  • 书中提到的指定初始化方法(designated initializer)不明白,根据书中后面的"其它初始化方法与初始化方法链的理解",指定初始化方法不同在于可以供其它初始化方法调用,但不调用其它初始化方法,通常参数最多。
  • selfsuper
    • self为类或对象自身,存在于方法中,是一个隐式(implicit)局部变量,相当于c++的this
    • super为父类,向super发消息,其实就是向self发消息,但是要求系统再查找方法时跳过当前对象的类,从父类开始查询。
  • 在初始化方法中应该直接访问实例变量,而不是使用存取方法。因为初始化方法执行时,无法确定新创建对象是否已经处于正确设置,所以应该直接访问类中实例变量。(其实这只是习惯问题)
  • 初始化方法总结的若干规则:

    • 类会继承父类所有的初始化方法,也可以加入其它初始化方法。
    • 初始化方法要直接或间接调用父类的指定初始化方法。
    • 其它初始化方法要直接或间接调用自身的指定初始化方法。
  • 类方法的声明和实例方法的声明差别在于第一个字符,实例方法为-,类方法为+

  • 在头文件中实例变量声明写在最前面,然后是类方法,接下来是初始化方法,最后是其它方法。这也是一种约定规范。
  • 在Objective-C中,如果某个类方法的返回类型是这个类的对象(例如:stringWithFormat:),就可以将该类方法称为便捷方法(convenience method)。

2.5 深入学习NSArray与NSMutableArray

  • Objective-C数组相关:
    • 可以存储不同类型继承自NSObject的对象指针,不能保存基本C类型变量。
    • 不能将nil加入数组,可以用NSNull代替,例如:[items addObject:[NSNull null]];
    • 访问数组可以使用下标语句NSString *foo = items[0];或发消息NSString *foo = [items objectAtIndex:0];,这两种方法效果是相同的。
  • 现在方括号的作用有3种:发送消息、存取方法、访问数组,如果使用点语法存取方法,下标语法访问数组,可以清晰突出发送消息代码。
  • NSMutableArray中,可以使用下标语法向数组中添加和修改对象,等价于insertObject:atIndex:replaceObjectAtIndex:withObject:发消息。

2.6 异常与未知选择器

对书中的疑惑:

  • 书中意思是说所有类对象都是运行时绑定,但是感觉并不是所有OC对象都是运行时(runtime)绑定,除了书中展示的使用id来接收创建的对象时,这时候书中所说的isa可能就不起作用了?

2.12 如何为类命名

  • OC没有提供命名空间机制,为了区分类,需要为类添加前缀。例如,开发一个MovieView应用,就可以在所有和项目相关的类名前加上MOV。
  • Apple提供的类名都为2个字符前缀,为了减少与Apple未来发布类产生冲突的可能,我们要使用至少3个字符前缀。

2.13 #import和@import

  • @import Fundation告诉编译器需要使用Foundation框架,之后编译器会优化预编译头文件和缓存编译结果过程,文件中不再明确引用框架,编译器会根据@import自动导入相应框架。
  • 目前只有Apple提供的框架可以使用@import,如果需要导入自己写的类和框架,只能使用#import

新版本的Xcode已经不会自动创建预编译头文件,因为预编译头文件会带来代码复用困难等问题。

3 通过ARC管理内存

3.1 栈

  • 执行方法或函数是从内存栈(stack)中分配空间,每块空间称为帧(frame),用来保存方法内声明的变量值。
  • 调用main函数时栈的变化过程如下图:

3.1

3.2 堆

  • 堆(heap)是内存中另一块区域,和栈是分开的。
  • 栈和堆区别是:栈按后进先出规则保存一组帧,堆则包含了大量无序的活动对象,需要通过指针来访问。

  • 发送alloc消息是从堆上分配内存。

  • iOS应用通过ARC来自动完成堆内存管理工作。

3.3 指针变量与对象所有权

  • 如果堆内存中对象,没有指针指向它的话就会被释放掉,系统会自动记录有多少对象指针引用它,1个引用ARC就为1,2个为2,0个内存会被释放。
  • NSObject实现了一个名为dealloc的方法,当某个对象即将被释放时,程序会调用该方法。

3.4 强引用与弱引用

  • 只要指针变量指向了某个对象,那么相应的对象就会多一个引用计数,并且不会被释放。这种指针特性称为强引用(strong reference)。
  • 也可以选择让指针变量不影响某指向对象的引用计数,这种不会改变对象拥有者个数的指针特性称为弱引用。
  • 弱引用用来解决强引用循环问题(strong reference cycle,也称保留循环),当两个以上对象相互之间有强引用时就回产生强引用循环。

强引用循环问题

  • 存在强引用循环问题如下图:

3.4

  • 图中两个BNRItem对象中包含两个指向BNRItem对象的指针_container和_containerItem互相指向彼此。

  • 当items设置为nil后,没有两个BNRItem对象引用计数减1,但是互相依然强引用,所以内存无法释放,如下图:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值