- 创建: [2013-3-15, 10:00]
- Objective-C 基础知识
- 创建一个简单的App并进行测试
- 如何将应用发布到App Store
安装准备工作
- 通过这个教程我将学习创建一个接受用户输入并将其显示到屏幕上的应用。
是线路图中最长的文章,为以后的学习奠定了基础
- 将会学到如何将应用程序国际化。
- 开发iPad的几乎等效与开发iPhone。
-
创建和测试新项目
- 创建一个Hello World项目(在该项目中加注释来做笔记)
- 在 Simulator 中运行
-
了解应用程序如何启动
- Xcode 自动创建的应用程序对象会建立一个循环(循环会将输入源寄存,并将输入事件传递给应用程序)该类叫做UIApplicationMain由UIKit提供。
- UIKit 框架提供了构建和管理应用程序界面的所有类。
- 窗口(Window?)对象的特性: a. 为应用程序的可见内容提供容器; b. 协助将事件传递到应用程序对象; c. 协助应用程序对设备的摆放作出响应; d. 窗口对象本身是不可见的。
- 串联图 --> *.storyboard, 串联图定义了应用程序的用户界面,其中包括对象、转换和连接的归档。
- 视图可以嵌套组织形成一个视图层次,一个视图控制器只能用来管理一个层次的视图。
- MVC --> 视图知道如何显示模型中的数据,控制器充当视图和模型的媒介。
- 视图控制器的组成: a. "first responder"一个第一响应器占位符对象; b. 名为 Exit 的占位符对象,用于展开序列(可以用来展开任意一个场景); c. HelloWorldViewController 对象; d. 一个视图。
-
小结
-
[暂停: 3-15, 12:00]
<< easy >>
- 使用检查器来检查视图控制器
- 更改视图的背景颜色
- 小结
-
添加用户界面元素 Cocoa Touch自动布局系统会在我们进行自动布局操作时在Consraints栏下创建一些约束条目。
-
为按钮创建操作
- 一个按钮操作的运作过程: a. 按钮发送一个操作给视图控制器; b. 视图控制器先更改字符串模型对象来响应消息; c. 然后,视图控制器更新相应的UI中的文本。
-
为文本栏和标签创建 Outlet
- Outlet 描述了两个对象之间的连接,当需要让一个对象(比如视图控制器)和其包含的对象(比如一个Label)进行通信,需要给那个被包含的对象指定一个Outlet。
- IBAction --> 是一个关键字,用来告诉 Xcode 将一个方法作为<目标-操作连接>的操作部分来处理。IBAction被定义为 void。
- IBOutlet --> 和IBAction一样,只是为了方便 Xcode。
-
建立文本栏的委托连接
- 为文本栏建立委托的目的:当用户点击虚拟键盘上的“Done”时,视图控制器可以让虚拟键盘消失。
-
让应用程序具有辅助功能
-
测试应用程序
-
小结 我们可以方便的借助Xcode拖拽建立连接的方式从而避免自己写很多代码,这同时也可以减少犯错的机会。
-
为用户姓名添加属性
- 一个属性声明(比如userName)会让编译器自动生成存取方法(getter, setter), 还会成一个下划线开头的实例变量(比如_userName)。
-
实施 changeGreeting: 方法
- userName 属性的设置有其必要性,它扮演者MVC中模型对象的角色,依赖文本栏中的字符串是不对的,单其中的原因又是什么呢?有待考虑…
-
将视图控制器配置为文本栏的委托
- 因为无法直接从应用程序向键盘发送消息,所以要通过让文本栏自己释放焦点的形式来让键盘随之消失。
- 步骤 a. 采用UITextFieldDelegate协议 b. 实现 textFieldShouldReturn: 方法
-
测试应用程序
-
小结
- 代码和编译器警告
- 警告不能被忽视。
- 检查串联图文件
- 按住 Control 键点击相应的对象来查看连接面板。
- 委托方法的名称
- 最好用只能补全来给出。
- 代码清单
-
[暂停: 03-15, 18:02]
-
[开始: 03-16, 10:00]
-
自定工作区
-
在iOS Simulator中测试应用程序
-
在iOS设备上测试应用程序 在模拟器上并没有运行在设备上的所有线程。
-
快速查找 Xcode 帮助
-
提高应用程序的性能
-
管理应用程序的版本
-
分发和发布您的应用程序 没有许可证没法导出归档文件
-
Objective-C是C语言的超集
- 相对于ANSI C,Objective-C添加的语法和功能: a. 定义新的类 b. 类和实例的方法 c. 实例方法(发送消息) d. 属性声明(自动生成存取方法) e. 静态和动态类型化 f. 块(block), 已封装的,可以在任何时候执行的多段代码 g. 基本语言的扩展(如协议和类别)
- Objective-C的动态特性可以让大部分符号解析的责任转移到运行时。
-
类和对象
- 创建对象需要两步: a. 分配内存 b. 初始化对象
- 类的规格需要接口(头文件)和实现(源代码文件)两部分,其中接口部分给出(声明)公共的方法,实现部分给出(实现)方法的细节。如果需要定义一个私有(专有)的方法,其声明和相应的实现都应该出现在实现文件中。
- #import 指令确保同一个文件只被导入一次,如果想要导入一个框架的大部分或者所有文件只需要导入其包罗头文件(umbrella header file)。
- 类声明指令 --> 以 @interface 指令开头,以 @end 指令结束,期间为属性和方法的声明,作为类的公共接口。
- 一个引用了对象的变量即可以进行静态类型化(立即指定其类型)也可以进行动态类型化(先指定该对象类型为id, 在运行时指定其类型)。对于后者可以体现语言的动态特性,在处理对象集合(collection)时非常有用,就不用像java那样使用丑陋的泛型来解决问题。
-
方法和发消息
- 签名关键字的组合(冒号也是必须的,表示有参数存在)才是一个方法真实的名字。
- 嵌套的消息表达式可以避免发送消息时声明大量临时变量。
- 调用一个对象的<存取方法>可以使用简洁的<点记法语法>。object.attr (例如,self.userName = self.textField.text;)
-
已声明的属性和存取方法
- 使用类方法一般都是将类方法用作工厂方法来生成新的实例,或者存取类的共享信息。
- 可以在类的源文件中声明专有属性,控制器对象(如委托和视图控制器)的属性通常应该为专有的。
- 属性的类型:
- copy: Copy the object ding assignment
- readonly: Declare only a getter method
- weak: Declare delegate as a weak reference
- 可以通过 @synthesize 编译指令来自定义属性的实例变量(而不是自动的以下划线(_)开头的实例变量)。
-
块 (Objective-C 中闭包的主要载体)
- 块本质上是一个<可移植的匿名函数>,可以作为参数传入方法或函数,也可以被它们返回,当然也可以被调用。(很像一个被赋值的函数指针不是吗,感觉这可以极大简化回调的设计)。
- 在方法中声明的块可以共享其此法作用域(包括方法中的参数和变量,函数和全局变量),默认这种共享是只读的,但是在声明的变量前加上 (__block)修饰则可进行读写访问。那么,块根本就是做为回调函数而存在的嘛,这样写起GUI程序来将非常方便。
-
[暂停: 03-16, 15:22]
-
[开始: 03-20, 10:57]
-
协议和类别
- 类比 java 中的接口即可,区别是 <协议> 中的方法可以不实现
- 协议使用 @protocal 指令来声明。
- 类别 --> 目的是为了让大型代码结构更清晰。它允许别的类往一个已存在的类中添加方法,用来添加或覆盖目标类中的方法。
-
已定义的类型和编码策略
- 一些特殊的变量名: a. @开头的编译器指令 b. 已定义的类型和其类型的字面常量。 c. super, self
- 几种中欧那个要的类型 a. id, 动态对象类型 -- nil b. Class, 动态类类型 -- Nil c. SEL, 选择器数据类型 -- NULL d. BOOL, 布尔类型 -- YES/NO
-
[开始: 03-21, 11:06] - Foundation 框架种定义了3种极其基础的类和协议
- 根类及其相关协议
- 值类
- 集类
- 作为其它所有新类的基础,定义了一些基础协议。
- 对象直接的关系形成对象图
- 强耦合的对象可以轻松发送消息,弱耦合的对象要依赖设计模式方便通信。
- 调用 alloc 之后,运行时会在分配相应内存之后,还会将实例变量清零。
- 初始化方法以init开始,并返回一个类型为id的对象。
- NSString 的工厂方法,使创建对象更方便:
+ (id)stringWithFormat:(NSString *)format, …;
- 虽然有自动引用计数(ARC),但是强应用形成的引用循环还是会导致内存泄漏。
- 避免强引用循环的方式是明智地使用弱引用。
- 有以下几种使用弱引用的方式:
- 委托:@property(weak) id delegate;
- 未引用顶级对象的 Outlet: @property(weak) IBOutlet NSString *theName;
- 目标(?):(void)setTarget:(id __weak)target
- 块内对 self 的引用。
__block typeof(self) tmpSelf = self; [self methodThatTakesABlock:^ { [tmpSelf doSomething]; }];
- 一些内置的不可变类会有其对应的可变对象,其名称中包含"Mutable"
-
使用值对象的基本知识 将值类的实例声明为属性时,应该使用 copy 选项。
int n = 5; // Value assigned to primitive type NSNumber *numberObject = [NSNumber numberWithInt:n]; // Value object created from primitive type int y = [numberObject intValue]; // Encapsulated value obtained from value object (y == n)
-
字符串和 NSString 字面常量
// Create the string "My String" plus carriage return. NSString *myString = @"My String\n"; // Create the formatted string "1 String". NSString *anotherString = [NSString stringWithFormat:@"%d %@", 1, @"String"]; // Create an Objective-C string from a C string. NSString *fromCString = [NSString stringWithCString: "A C string" encoding:NSASCIIStringEncoding];
-
NSNumber 字面常量
-
-
日期和时间
- 日期对象封装自参考日期开始算起的时间间隔(以秒为单位),那个参考日期为:2001-01-01开始的那一刻。
- 通常需要配合 NSCalendar, NSDateComponents; NSTimeZone; NSLocale 来有意义得使用日期。
- 集合。。。| 最重要的有3种集合类型(array, dictionary, set),每种集合类型都有相应的不可变和可变类型。
-
[开始: 03-23, 13:50]
- 发现对象是否是特定类或其子类的实例
- isKindOfClass
- 发现对象是否响应消息
- [obj responsToSelecrot:@selector(method:)]
- 发现对象是否遵守协议
- [obj conformsToProtocol:@protocol(SomeProtocol)]
- 相等:isEqual
- 相同:==
- 接受对象(被拷贝的对象)的类必须遵守 NSCopying 协议,并实现copy方法
- 可以声明 mutableCopy 方法来创建其可变副本
通过框架提供的API来利用框架,API以头文件的形式指定可用的类,数据结构和协议。
- 框架的层级:
- Cocoa Touch
- UIKit
- Media
- Core Graphics
- Open GL ES
- Core Animation
- Core Services
- Core Data
- Foundation
- Core OS
- Cocoa Touch
-
Foundation 框架为所有应用程序提供基本的系统服务
- 创建和管理基础数据结构
- 访问存储在应用程序中的资源(图像,网络设备,URL流)
- 发布和观察通知
- 异步执行代码
- ...
-
UIKit 框架提供的类,可用于创建基于触摸的用户界面
- 构建和管理用户界面
- 处理基于触摸和运动的事件
- 优化程序以实现多任务
- ...
-
Core Data 框架管理应用程序的数据模型
- 用来管理对象图
- 内建 SQLite 技术
-
Core Graphics 框架用来创建图形
- 应该尽可能使用较高级的UIKit框架绘图(简单便捷),而非较低级的 Core Graphics
- 使用Core Graphics(也称为Quartz)是为了可以在iOS和OS X 之间直接共享绘图代码
- Core Graphics 可以(5项):
- 制作基于路径的绘图
- 使用边缘模糊效果
- 添加渐变、图像和颜色
- 进行坐标空间变换
- 创建、显示和解析PDF文档
-
Core Animation 框架用来制作高级动画和视觉效果
- Core Animation可以(5项):
- 创建自定义动画
- 给图形添加时序功能
- ...
- Core Animation可以(5项):
-
OpenGL ES 框架提供2D和3D绘图工具
- OpenGL ES:
- 创建2D和3D图像
- 制作复杂的图形,如数据可视化和游戏
- 访问底层图形硬件
- OpenGL ES:
- 框架会将将某种设计强加与我们写的程序,或者至少会强加域我们要尝试解决的某个问题空间
-
核心对象网络有两个主要的任务:
- 绘制初始的图形界面
- 处理用户和图形界面之间交互的事件
-
主要事件循环:
- 用户触摸屏幕
- 操作系统将触摸事件加入事件队列
- 应用程序对象 读取事件队列中的事件并交由核心对象来处理
- 核心对象处理完后请求操作系统来更新用户界面
-
写应用的一个重要的方面是对框架类的一种定制
-
使用框架和将代码与框架整合有两种方式:
- 使用现成的类创建实例对象
- 子类话通用的类将框架代码引入到应用程序当中
-
将框架类子类化是主要的但不是唯一的很多时候也不是首选的整合技巧
- 何时创建子类
- 当你想要进行子类化时你需要考虑的因素以及需要作出的努力:
- 了解框架 熟悉框架中每个类的目的和功能
- 明确自己的应用程序需要做什么
- 定义子类实例扮演的角色(描绘其在对象图中的位置?)
- 当你想要进行子类化时你需要考虑的因素以及需要作出的努力:
- 覆盖方法
- 调用还是覆盖?
- 覆盖的方法通常不是亲自调用的方法
- 一般框架声明的公共方法会被用作以下两种用途:
- 调用它们,以使用该类提供的服务
- 覆盖它们,让你的代码可以引入到框架定义的程序模型当中
- 调用超类实现
- super 关键字的使用
因为框架中使用了很多设计模式,所以为了更高效地使用框架,有必要去学习设计模式。同时使用设计模式也会让你写出高复用,高扩展性的程序(当然, 在像 Objective-C 这样低级的语言中是这样的)。
- 封装原则告诉我们隔离并封装(将其独立出来)系统中的可变部分可以减少系统各部分的耦合性,从而使整个系统更加灵活。
- 模型对象
- 视图对象
- 分离是为了重用的方便
- 控制器对象
-
$$ 对象之间的关系时复杂而动态的,我们需要利用设计模式来组织对象之间的合作关系。
-
[暂停: 03-23, 17:00]
-
[开始: 03-24, 13:00]
-
委托:代表另一个对象
- 委托对象通常返回一个 Boolean 值来告诉被委托的对象是否执行相应操作。
- 子视图控制器可以通过委托的方式将某些值传达到父视图控制器
-
协议:使不相关的对象之间能通过继承进行通信
- 通常作为框架实施委托的一部分
-
通知中心:通知对事件感兴趣的观察者
- 任何对象都可以观察通知,但必须进行注册,进行注册时需要给出被调用的方法,而且此方法只有唯一参数(即发送通知的对象)
-
目标-操作:事件发生时封装待发送的消息
- 费解 …
-
健值观察:值更改时通知观察者
- 允许对象在另一个对象的属性发生改变是得到通知
-
基于设计模式的其他框架设计
- 视图层次:视图之间的包含关系会形成层次结构
- 响应器链:类似与javascript中的事件冒泡
- 前台:从一个执行环境重定向到另一个环境,比如从后台任务中跳回来进行UI处理
- …
- 良好用户体验所要考虑的7个方面:
- 隐喻
- 一致性
- 直接操控
- 反馈和通信
- 美学集成度
- 用户控制
- 心智模式
- 务必阅读 iOS Human Interface Guidelines
-
理解用户如何使用他们的设备
- 程序应该迅速启动,并能适应各种环境
- 当用于专注于使用程序时,就不那么在意屏幕尺寸了
- 放在系统设置中的设置项应该是不常改的类型,因为要修改那些设置必须退出当前程序,最好可以在程序中就进行设置。
-
学习基本的用户界面原则
- 美学集成度:考察一个程序的外观和其功能的融合程度。
- 一致性:尽量和iOS默认的那些程序行为相一致……
- 直接操控
- 反馈:一般操控时用户希望得到即时反馈,长时间操作时,用户希望看到状态进度
- 隐喻:使对程序中虚拟对象的操作和现实世界中的对象和操作联系起来
- 用户控制:需要在给用户足够的控制和避免危险的结果之间寻找平衡
-
遵循指南
- 用户体验指南
- 聚焦于主要任务
- 让用法简单明确
- 使用以用户为中心的术语
- 制作指尖大小的目标
- 不强调设置(即给出优化过的默认配置)
- 一致地使用用户界面元素
- 使用形象的动画来沟通
- 仅在必要时需要用户进行存储
- iOS技术指南(用户会认为有必要整合一些通用的功能):
- 支持 iCloud 存储
- 做好多任务相关的中断和恢复准备
- …
- UI元素使用指南:
- 确保导航栏中有返回按钮,并显示上一个屏幕的标题
- [当标签功能不可用时,不要将标签从标签栏移除]
- [避免提供“隐藏弹出式窗口”按钮]
- 当用户选择表格视图所列出的项目时,要提供反馈(好严格)
- 在iPad上,仅在弹出式窗口内显示挑选器
- 使用系统提供的按钮和图表时,要遵循它的含义
- 用户体验指南
-
利用一些经过验证的设计策略
- 提炼功能列表:并不是越多越好,要把握重点
- 为设备而设计:为不同设备设计不同的 UI 是有必要的
- 原型和迭代:确定功能后,即可开始创建可测试原型,早期的原型不需要显示真实的UI和美工图样,也不需要处理真实的内容,旨在让测试人员来测试出程序中潜在的问题。
- 大多数程序只有一个UIWindow对象,有些程序会有多个UIWindow对象用来将内容显示在外接显示器上。
-
定义自定数据模型
- NSIndexPath --> 存储数字列表,通常用来指定层次列表中的多层选择
- iOS中的URL是存储文件路径的首选方式
- 支持撤销操作的技巧:
- 相应定义的方法,使其对对象的修改是对称的
- 把业务逻辑从修改成员变量值的代码中分离出来
- 对于多步操作,使用现有的 NSUndoManager,将步骤组合起来
-
使用 Core Data 定义结构化数据模型
- 用来持久化模型对象
- 支持自动撤销和重做
- 具有版本管理功能!!!
-
定义基于文稿的数据模型
- 使用UIKit 视图构建界面
- 使用视图和OpenGL ES 构建界面
给出了一个iOS应用程序的 文件组成 表格:一个典型的应用程序捆绑包