SlideShare uma empresa Scribd logo
1 de 54
Baixar para ler offline
Objective-C




范圣刚,princetoad@gmail.com,www.tfan.org
• Objc 基础
• 通过⼀一个RandomPossessions 的⼩小程序看⼀一下有
 关:类,实例,对象,消息,初始化⽅方法,类⽅方
 法,数组,字符串和格式化字符串,访问器,异
 常
Objective-C
• iOS 应⽤用
• Objective-C: C 语⾔言的扩展
• Cocoa Touch: Objective-C 类的集合
• ⾯面向对象编程(object-oriented programming)
对象
Party的表⽰示
• 属性
 • 名称
 • ⽇日期
 • 受邀⼈人列表
• 操作
 • 发送email提醒
 • 打印名称标签
 • 取消party
C
• 结构体
    • 数据成员
    • 类型和名称
• malloc
• C 函数
Class
•类
•实例
•结构体成员和实例变量
•⽅方法:名称,返回值类型,参
数列表,实例变量访问
•运⾏行⽅方法:message
使⽤用实例
使⽤用实例
• 使⽤用类的实例
• 指向对象的变量
• 指针变量 -> 对象在内存中的地址
• 指向对象的变量声明:Party *partyInstance;
• 只是⼀一个可以指向 Party 对象的变量,不是对象本
⾝身。
创建对象
• 对象的⽣生命周期:被创建,发送消息,不⽤用的时
 候销毁
• alloc 消息:Party *partyInstance = [Party alloc];
• 当你拥有⼀一个指向实例的指针时,就可以向它发
 送消息
• 第⼀一个消息 -> initialization 消息:[partyInstance
 init];
• 合并:Party *partyInstance = [[Party alloc] init];
• nested message send
发送消息
消息剖析
• 中括号中
• 三个部分
 • receiver: ⼀一个指向被要求执⾏行⽅方法的对象的指针
 • selector: 要执⾏行的⽅方法的名称
 • arguments: 作为参数提供给⽅方法的值
• [partyInstance addAttendee:somePerson]
 • 发送 addAttendee: 消息给 partyInstance(receiver) 触发
   addAttendee: ⽅方法(通过 selector 命名)并且传⼊入
   somePerson(⼀一个argument)

• message 可以有⼀一个参数,多个参数,或者没有参数
发送消息


receiver 是被发送消息的   selector 是被触发的⽅方法
                                       arguments 被⽅方法使⽤用
对象指针               的名称


 [ partyInstance addAttendee: somePerson
                      withDish: deviledEggs ]
其他语⾔言
   partyInstance.addAttendeeWithDish(somePerson, deviledEggs)

Objective-C
  [partyInstance addAttendee:somePerson withDish:deviledEggs];
销毁对象
• partyInstance = nil;
nil
 • if (venue == nil) ...
 • if (!venue) ...
 • 向 nil 变量发送消息
 • if (venue) { [venue sendConfirmation]; }
  • nil-check 是没有必要的
开始 RandomPossessions
把模板代码换成创建和销毁数组实例

 #import <Foundation/Foundation.h>

 int main(int argc, const char * argv[])
 {

      @autoreleasepool {

 //         // insert code here...
 //         NSLog(@"Hello, World!");
          // 创建⼀一个 mutable 数组对象,把它的地址保存到 items 变量
          NSMutableArray *items = [[NSMutableArray alloc] init];

          // 销毁 items 指向的对象
          items = nil;

      }
      return 0;

 }
• ⼀一但实例化完数组以后,我们就可以给它发送消
     息了,例如 addObject: 和 insertObject:atIndex


int main(int argc, const char * argv[])
{

     @autoreleasepool {

//        // insert code here...
//        NSLog(@"Hello, World!");
        // 创建⼀一个 mutable 数组对象,把它的地址保存到 items 变量
        NSMutableArray *items = [[NSMutableArray alloc] init];

        // 向 items 发送 addObject: 消息,每次传递⼀一个字符串
        [items addObject:@"One"];
        [items addObject:@"Two"];
        [items addObject:@"Three"];

        // 发送另外⼀一个消息 insertObject:atIndex 给同样的数组对象
        [items insertObject:@"Zero" atIndex:0];
• 为了确认这些 string 被添加到了数组,我们来加
⼀一段代码把它们打印出来

• 构建并运⾏行,看⼀一下控制台的输出
  // 遍历数组
  for (int i=0; i < [items count]; i++) {
      // 隐式发送 description 消息
      NSLog(@"%@", [items objectAtIndex:i]);
  }
创建字符串
• [items addObject:@”One”];
• @符号 + 字符串 = Objective-C 中的硬编码字符串
• NSString 的实例
• alloc?
• @:仅针对 NSString 的⽅方便的⽣生成字符串的缩写
 NSString *myString = @"Hello, World!";
 int len = [myString length];

 len = [@"Hello, World" length];

 myString = [[NSString alloc] initWithString:@"Hello, World!"];
 len = [myString length];
格式化字符串
• NSLog 打印到控制台,接收可变数量的参数
• 第⼀一个参数是必须的,⽽而且必须是 NSString 实例,称
 作 format string,包含⽂文本和⼀一些 token。

• token 以百分号%作为前缀
• 每⼀一个传给函数的附加参数替换掉 format string 中的
 ⼀一个token
• token 同时也指定了他们对应的参数的类型
 int a = 1;
 float b = 2.5;
 char c = 'A';
 NSLog(@"整数: %d 浮点数: %f 字符: %c", a, b, c);
%@
• 任何对象
• description 消息,返回⼀一个 NSString
• 所有对象都实现了 description 消息
NSArray 和 NSMutableArray
• NSArray
 • 不可变数组
 • 实例化之后就不能再增加或者删除对象了
• NSMutableArray
 • NSArray ⼦子类
 • 可变数组
 • 可以被修改(动态增加删除对象)
指针,引⽤用和内存地址
数组能放什么?
• 数组只能持有 Objective-C 对象的引⽤用
• 基本数据类型和 C 结构体不能增加到数组
• ⼀一个单独的数组可以包含不同类型的对象
• 和强类型语⾔言不同
数组操作
• ⼤大⼩小:int numberOfObjects = [array count];
• addObject: 在数组最后增加对象
• insertObject:atIndex: 在特定位置插⼊入对象
• 注意:不能往数组中增加 nil ,可以使⽤用 NSNull
 • [array addObject:[NSNull null]]
• objectAtIndex: 获取数据
⼦子类化⼀一个 Objective-C 类
• 层次结构 (hierarchy)
• 只有⼀一个超类(superclass)
• NSObject
 • root class
 • ⾓角⾊色是实现所有 Cocoa Touch 中的对象的基本⾏行为
 • alloc, init, description
类的层次结构
• 扩展
• 重写
创建⼀一个NSObject 的⼦子类
• target 勾选
• BNRItem, BNRItem.h, BNRItem.m
• 保留所有的 C 语⾔言关键字
• Objective-C 额外的关键字使⽤用@前缀区分
• 关键字 @interface 在 Objective-C 中声明⼀一个类
• 冒号后跟⽗父类
• 只允许单⼀一继承
 • @interface ClassName : SuperclassName
 • @end 指⽰示类已经被完全声明了
实例变量
类的实例变量紧跟类的声明之后,在
⼤大括号中进⾏行声明

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
    NSString *itemName;
    NSString *serialNumber;
    int valueInDollars;
    NSDate *dateCreated;
}

@end
BNRItem 实例
访问器⽅方法
• 有了实例变量之后,要能够 get,或 set 他们的值
• get/set 实例变量的⽅方法称作 accessors, 或者分别
 叫做getters 和 setters.
• Objective-C 的 setter ⽅方法名:set + 实例变量名
• getter ⽅方法名:和实例变量名⼀一样
BNRItem 访问器⽅方法
#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
    NSString *itemName;
    NSString *serialNumber;
    int valueInDollars;
    NSDate *dateCreated;
}

- (void)setItemName:(NSString *)str;
- (NSString *)itemName;

- (void)setSerialNumber:(NSString *)str;
- (NSString *)serialNumber;

- (void)setValueInDollars:(int)i;
- (int)valueInDollars;

- (NSDate *)dateCreated;

@end
实例⽅方法
    • description
    • 重写:在实现⽂文件中定义,不需要再做声明
// 重写 description
- (NSString *)description
{
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@ (%@): 价值 $%d, 登记
⽇日期 %@",
     itemName, serialNumber, valueInDollars, dateCreated];

    return descriptionString;
}
初始化器
• alloc -> ⽣生成⼀一个实例,返回⼀一个指向它的指针
• init -> 给所有的实例变量初始化值
• ⾃自定义初始化过程简化代码
• 命名习惯:以init开头
BNRItem 的 Initializer
• ⽅方法名(或者叫selector)是:
 initWithItemName:valueInDollars:serialNumber:
• 这个selector 具有三个 label:initWithItemName:,
 valueInDollars:, 和 serialNumber:。表明⽅方法接收三
 个参数
• 这些参数每个都有⼀一个类型和⼀一个参数名
• 类型在圆括号中,参数名紧跟类型
    }
    - (id)initWithItemName:(NSString *)name
            valueInDollars:(int)value
              serialNumber:(NSString *)sNumber;
    - (void)setItemName:(NSString *)str;
id
• 返回值类型是id
• 指向任意对象的指针
• BNRItem * ?
• ⼦子类化的问题
isa
• 从 initializer 返回的对象的类型我们是知道的(向
  类发送 alloc )
• 对象⾃自⾝身也知道它⾃自⼰己的类型 isa 指针
• 每个对象都有⼀一个名为 isa 的实例变量
• 当⼀一个实例通过向类发送 alloc 创建的时候,类把
  返回的对象的 isa 实例变量设成指回到⽣生成它的类
• isa 指针的意思就是说这个对象是⼀一个这个类的实
  例
isa 指针
实现designated initializer
     • 第⼀一件事,使⽤用 super 调⽤用超类的初始化器
     • 最后,使⽤用 self 返回成功初始化过的对象
// 实现初始化⽅方法
- (id)initWithItemName:(NSString *)name valueInDollars:(int)value
serialNumber:(NSString *)sNumber
{
    // 调⽤用⽗父类的指定的初始化器
    self = [super init];

    // 给实例变量初始化值
    [self setItemName:name];
    [self setSerialNumber:sNumber];
    [self setValueInDollars:value];
    dateCreated = [[NSDate alloc] init];

    // 返回初始化对象的地址
    return self;
}
理解 self
• 在⽅方法内部,self 是隐式的本地变量
• 不需要声明,⾃自动设成指向被发送消息的对象
• 可以⽤用于给⾃自⾝身发消息的情况下
• return self;
理解 super
• 重写⽅方法时保持超类⽅方法中的操作,在其上增加
 新的内容
• super:编译器指⽰示符
• 指定名称的⽅方法的查找顺序:对象类⾃自⾝身 -> 超类
 -> 超类的超类
• 给 super 发消息,直接跳过 self 本⾝身, 从其超类
 开始
• initializer 失败的话返回 nil
• self = [super init];
其他初始化器以及初始化链
 • ⼀一个或多个初始化⽅方法
 • 初始化⽅方法链式调⽤用的好处
   • 减少出错的机会
   • 代码更容易维护
// 使⽤用初始化⽅方法链,没有的参数可以传⼊入默认值
- (id)initWithItemName:(NSString *)name
{
    return [self initWithItemName:name
                   valueInDollars:0
                     serialNumber:@""];
}
重写 init



- (id)init
{
    return [self initWithItemName:@"Item"
                   valueInDollars:0
                     serialNumber:@""];
}
Initializer 链
initializer 简单规则
• 类从其超类继承了所有的 initializer,同时可以根据
 其⺫⽬目的任意增加
• 每个类选择⼀一个 initializer 作为其 designated
 initializer
• designated initializer 调⽤用超类的 designated
 initializer
• 类的任意其他 initializer 调⽤用类的 designated
 initializer
• 如果类声明了⼀一个和其超类不同的 designated
 initializer,超类的 designated initializer 必须被重写
 来调⽤用新的 designated initializer
使⽤用 initializer
• 检查重写的 init 是否⽣生效
• 使⽤用 designated initializer 替换掉设置实例变量的
 代码
类⽅方法
• ⽅方法
 • 实例⽅方法
 • 类⽅方法
• 实例⽅方法被发送给类的实例(像init)
• 类⽅方法被发送给类本⾝身(像alloc)
• 类⽅方法⼀一般不是被⽤用来创建⼀一个类的新的实例,
 就是⽤用来提取类的⼀一些全局属性
• 类⽅方法不能在实例上操作,或者访问实例变量
声明类⽅方法
• 实例⽅方法的声明: 在返回值前⾯面 使⽤用减号“-” 表⽰示
• 类⽅方法的声明:使⽤用加号“+” 字符
• convenience method:stringWithFormat,
 randomItem, 返回⾃自⾝身类型的对象
• 类⽅方法中的 self
 • 指向类本⾝身,⽽而不是实例
 • ⼦子类调⽤用的问题
测试⼦子类

 for (int i=0; i<10; i++) {
     BNRItem *p = [BNRItem randomItem];
     [items addObject:p];
 }

 for (int i = 0; i < 10; i++) {
     NSLog(@"%@", [items objectAtIndex:i]);
 }
异常和⽆无法识别的 Selectors
异常
• ⼀一个对象只会响应它的类实现了相关⽅方法的消息
• 动态类型的objc,编译时⽆无法确定
• 异常exception,run-time errors(运⾏行时错误,和
 编译时错误相对compile-time errors)
快速枚举

 for (int i = 0; i < 10; i++) {
     NSLog(@"%@", [items objectAtIndex:i]);
 }




• Objective-C 2.0 引⼊入了fast enumeration
 for (BNRItem *item in items) {
     NSLog(@"%@", item);
 }

Mais conteúdo relacionado

Mais procurados

iOS程序设计-数据持久化
iOS程序设计-数据持久化iOS程序设计-数据持久化
iOS程序设计-数据持久化qiyutan
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析Justin Lin
 
jQuery源码学习
jQuery源码学习jQuery源码学习
jQuery源码学习fangdeng
 
Underscore
UnderscoreUnderscore
Underscorecazhfe
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训yiditushe
 
Javascript share
Javascript shareJavascript share
Javascript shareXu Mac
 
合久必分,分久必合
合久必分,分久必合合久必分,分久必合
合久必分,分久必合Qiangning Hong
 
Docker進階探討
Docker進階探討Docker進階探討
Docker進階探討國昭 張
 
Kissy editor开发与设计
Kissy editor开发与设计Kissy editor开发与设计
Kissy editor开发与设计yiming he
 
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7Justin Lin
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7Justin Lin
 
Script with engine
Script with engineScript with engine
Script with engineWebrebuild
 
页游开发中的 Python 组件与模式
页游开发中的 Python 组件与模式页游开发中的 Python 组件与模式
页游开发中的 Python 组件与模式勇浩 赖
 
论 Python 与设计模式。
论 Python 与设计模式。论 Python 与设计模式。
论 Python 与设计模式。勇浩 赖
 
KISSY for starter
KISSY for starterKISSY for starter
KISSY for starteryiming he
 
從 Singleton 談 constructor
從 Singleton 談 constructor從 Singleton 談 constructor
從 Singleton 談 constructorLuba Tang
 
IOS入门分享
IOS入门分享IOS入门分享
IOS入门分享zenyuhao
 
09 UITableView and UITableViewController
09 UITableView and UITableViewController09 UITableView and UITableViewController
09 UITableView and UITableViewControllerTom Fan
 

Mais procurados (20)

iOS程序设计-数据持久化
iOS程序设计-数据持久化iOS程序设计-数据持久化
iOS程序设计-数据持久化
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析
 
jQuery源码学习
jQuery源码学习jQuery源码学习
jQuery源码学习
 
Underscore
UnderscoreUnderscore
Underscore
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训
 
Javascript share
Javascript shareJavascript share
Javascript share
 
合久必分,分久必合
合久必分,分久必合合久必分,分久必合
合久必分,分久必合
 
Docker進階探討
Docker進階探討Docker進階探討
Docker進階探討
 
Kissy editor开发与设计
Kissy editor开发与设计Kissy editor开发与设计
Kissy editor开发与设计
 
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
 
J Query Learn
J Query LearnJ Query Learn
J Query Learn
 
Script with engine
Script with engineScript with engine
Script with engine
 
页游开发中的 Python 组件与模式
页游开发中的 Python 组件与模式页游开发中的 Python 组件与模式
页游开发中的 Python 组件与模式
 
论 Python 与设计模式。
论 Python 与设计模式。论 Python 与设计模式。
论 Python 与设计模式。
 
Node way
Node wayNode way
Node way
 
KISSY for starter
KISSY for starterKISSY for starter
KISSY for starter
 
從 Singleton 談 constructor
從 Singleton 談 constructor從 Singleton 談 constructor
從 Singleton 談 constructor
 
IOS入门分享
IOS入门分享IOS入门分享
IOS入门分享
 
09 UITableView and UITableViewController
09 UITableView and UITableViewController09 UITableView and UITableViewController
09 UITableView and UITableViewController
 

Semelhante a 02 Objective-C

從模組到類別
從模組到類別從模組到類別
從模組到類別Justin Lin
 
iPhone,ios,Object-c基础入门
iPhone,ios,Object-c基础入门iPhone,ios,Object-c基础入门
iPhone,ios,Object-c基础入门Lucien Li
 
iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门Lucien Li
 
twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹twMVC
 
5, initialization & cleanup
5, initialization & cleanup5, initialization & cleanup
5, initialization & cleanupted-xu
 
Python面向对象开发基础篇
Python面向对象开发基础篇Python面向对象开发基础篇
Python面向对象开发基础篇modou li
 
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试lydiafly
 
12, string
12, string12, string
12, stringted-xu
 
Android resource-management
Android resource-managementAndroid resource-management
Android resource-managementLucas Xu
 
Clean code_1_Nameing
Clean code_1_NameingClean code_1_Nameing
Clean code_1_NameingChiaChun Liu
 
Ecmascript
EcmascriptEcmascript
Ecmascriptjay li
 
NeteaseBlog Objective-C Style Guide
NeteaseBlog Objective-C Style GuideNeteaseBlog Objective-C Style Guide
NeteaseBlog Objective-C Style Guidejenkinv
 
[圣思园][Java SE]Reflection
[圣思园][Java SE]Reflection[圣思园][Java SE]Reflection
[圣思园][Java SE]ReflectionArBing Xie
 
Backbone js and requirejs
Backbone js and requirejsBackbone js and requirejs
Backbone js and requirejsChi-wen Sun
 
2, object oriented programming
2, object oriented programming2, object oriented programming
2, object oriented programmingted-xu
 
基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程zhangdaiping
 

Semelhante a 02 Objective-C (20)

從模組到類別
從模組到類別從模組到類別
從模組到類別
 
I os 02
I os 02I os 02
I os 02
 
iPhone,ios,Object-c基础入门
iPhone,ios,Object-c基础入门iPhone,ios,Object-c基础入门
iPhone,ios,Object-c基础入门
 
iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门
 
twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹
 
5, initialization & cleanup
5, initialization & cleanup5, initialization & cleanup
5, initialization & cleanup
 
Python面向对象开发基础篇
Python面向对象开发基础篇Python面向对象开发基础篇
Python面向对象开发基础篇
 
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试
 
12, string
12, string12, string
12, string
 
Javascript
JavascriptJavascript
Javascript
 
Android resource-management
Android resource-managementAndroid resource-management
Android resource-management
 
Clean code_1_Nameing
Clean code_1_NameingClean code_1_Nameing
Clean code_1_Nameing
 
Ecmascript
EcmascriptEcmascript
Ecmascript
 
NeteaseBlog Objective-C Style Guide
NeteaseBlog Objective-C Style GuideNeteaseBlog Objective-C Style Guide
NeteaseBlog Objective-C Style Guide
 
ios分享
ios分享ios分享
ios分享
 
[圣思园][Java SE]Reflection
[圣思园][Java SE]Reflection[圣思园][Java SE]Reflection
[圣思园][Java SE]Reflection
 
Backbone js and requirejs
Backbone js and requirejsBackbone js and requirejs
Backbone js and requirejs
 
I os 08
I os 08I os 08
I os 08
 
2, object oriented programming
2, object oriented programming2, object oriented programming
2, object oriented programming
 
基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程基于原型的JavaScript面向对象编程
基于原型的JavaScript面向对象编程
 

Mais de Tom Fan

PhoneGap 通信原理和插件系统
PhoneGap 通信原理和插件系统PhoneGap 通信原理和插件系统
PhoneGap 通信原理和插件系统Tom Fan
 
HTML5 Web workers
HTML5 Web workersHTML5 Web workers
HTML5 Web workersTom Fan
 
Web sockets
Web socketsWeb sockets
Web socketsTom Fan
 
Semantics
SemanticsSemantics
SemanticsTom Fan
 
Multimedia
MultimediaMultimedia
MultimediaTom Fan
 
Intro to-html5
Intro to-html5Intro to-html5
Intro to-html5Tom Fan
 
Html5 history
Html5 historyHtml5 history
Html5 historyTom Fan
 
Geolocation
GeolocationGeolocation
GeolocationTom Fan
 
File api
File apiFile api
File apiTom Fan
 
Deviceaccess
DeviceaccessDeviceaccess
DeviceaccessTom Fan
 
Webstorage
WebstorageWebstorage
WebstorageTom Fan
 
Html5 最重要的部分
Html5 最重要的部分Html5 最重要的部分
Html5 最重要的部分Tom Fan
 
AT&T 的 HTML5 策略和应用现状
AT&T 的 HTML5 策略和应用现状AT&T 的 HTML5 策略和应用现状
AT&T 的 HTML5 策略和应用现状Tom Fan
 
PhoneGap 2.0 开发
PhoneGap 2.0 开发PhoneGap 2.0 开发
PhoneGap 2.0 开发Tom Fan
 
Android 平台 HTML5 应用开发
Android 平台 HTML5 应用开发Android 平台 HTML5 应用开发
Android 平台 HTML5 应用开发Tom Fan
 
HTML5 生态系统和应用架构模型
HTML5 生态系统和应用架构模型HTML5 生态系统和应用架构模型
HTML5 生态系统和应用架构模型Tom Fan
 
18 NSUserDefaults
18 NSUserDefaults18 NSUserDefaults
18 NSUserDefaultsTom Fan
 
15 Subclassing UITableViewCell
15 Subclassing UITableViewCell15 Subclassing UITableViewCell
15 Subclassing UITableViewCellTom Fan
 

Mais de Tom Fan (20)

PhoneGap 通信原理和插件系统
PhoneGap 通信原理和插件系统PhoneGap 通信原理和插件系统
PhoneGap 通信原理和插件系统
 
HTML5 Web workers
HTML5 Web workersHTML5 Web workers
HTML5 Web workers
 
Web sockets
Web socketsWeb sockets
Web sockets
 
Storage
StorageStorage
Storage
 
Semantics
SemanticsSemantics
Semantics
 
Multimedia
MultimediaMultimedia
Multimedia
 
Intro to-html5
Intro to-html5Intro to-html5
Intro to-html5
 
Html5 history
Html5 historyHtml5 history
Html5 history
 
Geolocation
GeolocationGeolocation
Geolocation
 
File api
File apiFile api
File api
 
Deviceaccess
DeviceaccessDeviceaccess
Deviceaccess
 
Css3
Css3Css3
Css3
 
Webstorage
WebstorageWebstorage
Webstorage
 
Html5 最重要的部分
Html5 最重要的部分Html5 最重要的部分
Html5 最重要的部分
 
AT&T 的 HTML5 策略和应用现状
AT&T 的 HTML5 策略和应用现状AT&T 的 HTML5 策略和应用现状
AT&T 的 HTML5 策略和应用现状
 
PhoneGap 2.0 开发
PhoneGap 2.0 开发PhoneGap 2.0 开发
PhoneGap 2.0 开发
 
Android 平台 HTML5 应用开发
Android 平台 HTML5 应用开发Android 平台 HTML5 应用开发
Android 平台 HTML5 应用开发
 
HTML5 生态系统和应用架构模型
HTML5 生态系统和应用架构模型HTML5 生态系统和应用架构模型
HTML5 生态系统和应用架构模型
 
18 NSUserDefaults
18 NSUserDefaults18 NSUserDefaults
18 NSUserDefaults
 
15 Subclassing UITableViewCell
15 Subclassing UITableViewCell15 Subclassing UITableViewCell
15 Subclassing UITableViewCell
 

02 Objective-C

  • 2. • Objc 基础 • 通过⼀一个RandomPossessions 的⼩小程序看⼀一下有 关:类,实例,对象,消息,初始化⽅方法,类⽅方 法,数组,字符串和格式化字符串,访问器,异 常
  • 3. Objective-C • iOS 应⽤用 • Objective-C: C 语⾔言的扩展 • Cocoa Touch: Objective-C 类的集合 • ⾯面向对象编程(object-oriented programming)
  • 5. Party的表⽰示 • 属性 • 名称 • ⽇日期 • 受邀⼈人列表 • 操作 • 发送email提醒 • 打印名称标签 • 取消party
  • 6. C • 结构体 • 数据成员 • 类型和名称 • malloc • C 函数
  • 9. 使⽤用实例 • 使⽤用类的实例 • 指向对象的变量 • 指针变量 -> 对象在内存中的地址 • 指向对象的变量声明:Party *partyInstance; • 只是⼀一个可以指向 Party 对象的变量,不是对象本 ⾝身。
  • 10. 创建对象 • 对象的⽣生命周期:被创建,发送消息,不⽤用的时 候销毁 • alloc 消息:Party *partyInstance = [Party alloc]; • 当你拥有⼀一个指向实例的指针时,就可以向它发 送消息 • 第⼀一个消息 -> initialization 消息:[partyInstance init]; • 合并:Party *partyInstance = [[Party alloc] init]; • nested message send
  • 12. 消息剖析 • 中括号中 • 三个部分 • receiver: ⼀一个指向被要求执⾏行⽅方法的对象的指针 • selector: 要执⾏行的⽅方法的名称 • arguments: 作为参数提供给⽅方法的值 • [partyInstance addAttendee:somePerson] • 发送 addAttendee: 消息给 partyInstance(receiver) 触发 addAttendee: ⽅方法(通过 selector 命名)并且传⼊入 somePerson(⼀一个argument) • message 可以有⼀一个参数,多个参数,或者没有参数
  • 13. 发送消息 receiver 是被发送消息的 selector 是被触发的⽅方法 arguments 被⽅方法使⽤用 对象指针 的名称 [ partyInstance addAttendee: somePerson withDish: deviledEggs ]
  • 14. 其他语⾔言 partyInstance.addAttendeeWithDish(somePerson, deviledEggs) Objective-C [partyInstance addAttendee:somePerson withDish:deviledEggs];
  • 16. nil • if (venue == nil) ... • if (!venue) ... • 向 nil 变量发送消息 • if (venue) { [venue sendConfirmation]; } • nil-check 是没有必要的
  • 18. 把模板代码换成创建和销毁数组实例 #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { // // insert code here... // NSLog(@"Hello, World!"); // 创建⼀一个 mutable 数组对象,把它的地址保存到 items 变量 NSMutableArray *items = [[NSMutableArray alloc] init]; // 销毁 items 指向的对象 items = nil; } return 0; }
  • 19. • ⼀一但实例化完数组以后,我们就可以给它发送消 息了,例如 addObject: 和 insertObject:atIndex int main(int argc, const char * argv[]) { @autoreleasepool { // // insert code here... // NSLog(@"Hello, World!"); // 创建⼀一个 mutable 数组对象,把它的地址保存到 items 变量 NSMutableArray *items = [[NSMutableArray alloc] init]; // 向 items 发送 addObject: 消息,每次传递⼀一个字符串 [items addObject:@"One"]; [items addObject:@"Two"]; [items addObject:@"Three"]; // 发送另外⼀一个消息 insertObject:atIndex 给同样的数组对象 [items insertObject:@"Zero" atIndex:0];
  • 20. • 为了确认这些 string 被添加到了数组,我们来加 ⼀一段代码把它们打印出来 • 构建并运⾏行,看⼀一下控制台的输出 // 遍历数组 for (int i=0; i < [items count]; i++) { // 隐式发送 description 消息 NSLog(@"%@", [items objectAtIndex:i]); }
  • 21. 创建字符串 • [items addObject:@”One”]; • @符号 + 字符串 = Objective-C 中的硬编码字符串 • NSString 的实例 • alloc? • @:仅针对 NSString 的⽅方便的⽣生成字符串的缩写 NSString *myString = @"Hello, World!"; int len = [myString length]; len = [@"Hello, World" length]; myString = [[NSString alloc] initWithString:@"Hello, World!"]; len = [myString length];
  • 22. 格式化字符串 • NSLog 打印到控制台,接收可变数量的参数 • 第⼀一个参数是必须的,⽽而且必须是 NSString 实例,称 作 format string,包含⽂文本和⼀一些 token。 • token 以百分号%作为前缀 • 每⼀一个传给函数的附加参数替换掉 format string 中的 ⼀一个token • token 同时也指定了他们对应的参数的类型 int a = 1; float b = 2.5; char c = 'A'; NSLog(@"整数: %d 浮点数: %f 字符: %c", a, b, c);
  • 23. %@ • 任何对象 • description 消息,返回⼀一个 NSString • 所有对象都实现了 description 消息
  • 24. NSArray 和 NSMutableArray • NSArray • 不可变数组 • 实例化之后就不能再增加或者删除对象了 • NSMutableArray • NSArray ⼦子类 • 可变数组 • 可以被修改(动态增加删除对象)
  • 26. 数组能放什么? • 数组只能持有 Objective-C 对象的引⽤用 • 基本数据类型和 C 结构体不能增加到数组 • ⼀一个单独的数组可以包含不同类型的对象 • 和强类型语⾔言不同
  • 27. 数组操作 • ⼤大⼩小:int numberOfObjects = [array count]; • addObject: 在数组最后增加对象 • insertObject:atIndex: 在特定位置插⼊入对象 • 注意:不能往数组中增加 nil ,可以使⽤用 NSNull • [array addObject:[NSNull null]] • objectAtIndex: 获取数据
  • 28. ⼦子类化⼀一个 Objective-C 类 • 层次结构 (hierarchy) • 只有⼀一个超类(superclass) • NSObject • root class • ⾓角⾊色是实现所有 Cocoa Touch 中的对象的基本⾏行为 • alloc, init, description
  • 30. 创建⼀一个NSObject 的⼦子类 • target 勾选 • BNRItem, BNRItem.h, BNRItem.m • 保留所有的 C 语⾔言关键字 • Objective-C 额外的关键字使⽤用@前缀区分 • 关键字 @interface 在 Objective-C 中声明⼀一个类 • 冒号后跟⽗父类 • 只允许单⼀一继承 • @interface ClassName : SuperclassName • @end 指⽰示类已经被完全声明了
  • 31. 实例变量 类的实例变量紧跟类的声明之后,在 ⼤大括号中进⾏行声明 #import <Foundation/Foundation.h> @interface BNRItem : NSObject { NSString *itemName; NSString *serialNumber; int valueInDollars; NSDate *dateCreated; } @end
  • 33. 访问器⽅方法 • 有了实例变量之后,要能够 get,或 set 他们的值 • get/set 实例变量的⽅方法称作 accessors, 或者分别 叫做getters 和 setters. • Objective-C 的 setter ⽅方法名:set + 实例变量名 • getter ⽅方法名:和实例变量名⼀一样
  • 34. BNRItem 访问器⽅方法 #import <Foundation/Foundation.h> @interface BNRItem : NSObject { NSString *itemName; NSString *serialNumber; int valueInDollars; NSDate *dateCreated; } - (void)setItemName:(NSString *)str; - (NSString *)itemName; - (void)setSerialNumber:(NSString *)str; - (NSString *)serialNumber; - (void)setValueInDollars:(int)i; - (int)valueInDollars; - (NSDate *)dateCreated; @end
  • 35. 实例⽅方法 • description • 重写:在实现⽂文件中定义,不需要再做声明 // 重写 description - (NSString *)description { NSString *descriptionString = [[NSString alloc] initWithFormat:@"%@ (%@): 价值 $%d, 登记 ⽇日期 %@", itemName, serialNumber, valueInDollars, dateCreated]; return descriptionString; }
  • 36. 初始化器 • alloc -> ⽣生成⼀一个实例,返回⼀一个指向它的指针 • init -> 给所有的实例变量初始化值 • ⾃自定义初始化过程简化代码 • 命名习惯:以init开头
  • 37. BNRItem 的 Initializer • ⽅方法名(或者叫selector)是: initWithItemName:valueInDollars:serialNumber: • 这个selector 具有三个 label:initWithItemName:, valueInDollars:, 和 serialNumber:。表明⽅方法接收三 个参数 • 这些参数每个都有⼀一个类型和⼀一个参数名 • 类型在圆括号中,参数名紧跟类型 } - (id)initWithItemName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)sNumber; - (void)setItemName:(NSString *)str;
  • 39. isa • 从 initializer 返回的对象的类型我们是知道的(向 类发送 alloc ) • 对象⾃自⾝身也知道它⾃自⼰己的类型 isa 指针 • 每个对象都有⼀一个名为 isa 的实例变量 • 当⼀一个实例通过向类发送 alloc 创建的时候,类把 返回的对象的 isa 实例变量设成指回到⽣生成它的类 • isa 指针的意思就是说这个对象是⼀一个这个类的实 例
  • 41. 实现designated initializer • 第⼀一件事,使⽤用 super 调⽤用超类的初始化器 • 最后,使⽤用 self 返回成功初始化过的对象 // 实现初始化⽅方法 - (id)initWithItemName:(NSString *)name valueInDollars:(int)value serialNumber:(NSString *)sNumber { // 调⽤用⽗父类的指定的初始化器 self = [super init]; // 给实例变量初始化值 [self setItemName:name]; [self setSerialNumber:sNumber]; [self setValueInDollars:value]; dateCreated = [[NSDate alloc] init]; // 返回初始化对象的地址 return self; }
  • 42. 理解 self • 在⽅方法内部,self 是隐式的本地变量 • 不需要声明,⾃自动设成指向被发送消息的对象 • 可以⽤用于给⾃自⾝身发消息的情况下 • return self;
  • 43. 理解 super • 重写⽅方法时保持超类⽅方法中的操作,在其上增加 新的内容 • super:编译器指⽰示符 • 指定名称的⽅方法的查找顺序:对象类⾃自⾝身 -> 超类 -> 超类的超类 • 给 super 发消息,直接跳过 self 本⾝身, 从其超类 开始 • initializer 失败的话返回 nil • self = [super init];
  • 44. 其他初始化器以及初始化链 • ⼀一个或多个初始化⽅方法 • 初始化⽅方法链式调⽤用的好处 • 减少出错的机会 • 代码更容易维护 // 使⽤用初始化⽅方法链,没有的参数可以传⼊入默认值 - (id)initWithItemName:(NSString *)name { return [self initWithItemName:name valueInDollars:0 serialNumber:@""]; }
  • 45. 重写 init - (id)init { return [self initWithItemName:@"Item" valueInDollars:0 serialNumber:@""]; }
  • 47. initializer 简单规则 • 类从其超类继承了所有的 initializer,同时可以根据 其⺫⽬目的任意增加 • 每个类选择⼀一个 initializer 作为其 designated initializer • designated initializer 调⽤用超类的 designated initializer • 类的任意其他 initializer 调⽤用类的 designated initializer • 如果类声明了⼀一个和其超类不同的 designated initializer,超类的 designated initializer 必须被重写 来调⽤用新的 designated initializer
  • 48. 使⽤用 initializer • 检查重写的 init 是否⽣生效 • 使⽤用 designated initializer 替换掉设置实例变量的 代码
  • 49. 类⽅方法 • ⽅方法 • 实例⽅方法 • 类⽅方法 • 实例⽅方法被发送给类的实例(像init) • 类⽅方法被发送给类本⾝身(像alloc) • 类⽅方法⼀一般不是被⽤用来创建⼀一个类的新的实例, 就是⽤用来提取类的⼀一些全局属性 • 类⽅方法不能在实例上操作,或者访问实例变量
  • 50. 声明类⽅方法 • 实例⽅方法的声明: 在返回值前⾯面 使⽤用减号“-” 表⽰示 • 类⽅方法的声明:使⽤用加号“+” 字符 • convenience method:stringWithFormat, randomItem, 返回⾃自⾝身类型的对象 • 类⽅方法中的 self • 指向类本⾝身,⽽而不是实例 • ⼦子类调⽤用的问题
  • 51. 测试⼦子类 for (int i=0; i<10; i++) { BNRItem *p = [BNRItem randomItem]; [items addObject:p]; } for (int i = 0; i < 10; i++) { NSLog(@"%@", [items objectAtIndex:i]); }
  • 53. 异常 • ⼀一个对象只会响应它的类实现了相关⽅方法的消息 • 动态类型的objc,编译时⽆无法确定 • 异常exception,run-time errors(运⾏行时错误,和 编译时错误相对compile-time errors)
  • 54. 快速枚举 for (int i = 0; i < 10; i++) { NSLog(@"%@", [items objectAtIndex:i]); } • Objective-C 2.0 引⼊入了fast enumeration for (BNRItem *item in items) { NSLog(@"%@", item); }