OC基础-day03

1#pragma mark - Day03_01_对象作为方法的返回值

1) 对象是可以作为方法的返回值的,返回值应该写这个类指针类型.

- (MkDog *)buyDog;

代表方法执行完毕之后,有1个HMDog对象返回.

这个时候.在方法结束之前,就必须要使用return返回1个符合类型的对象.

2) 本质上来说.

其实返回的是1个指定对象的地址

不用担心对象会被销毁.因为对象是存储在堆区的.

#pragma mark - Day03_02_类的属性和方法

1) 一个Target中的类无法直接在另外1个Target中访问.

2) 类的属性代表什么?

a. 类的属性代表这类事物具有的共同的特征

b. 类的属性代表这个类所拥有的东西.

c. 如何分析类有哪些属性?

就分析这个类拥有哪些东西?

拥有的东西就可以作为类的属性.

3. 类的方法代表什么?

a. 代表这个类所具备的行为. 这个类所具备的功能.

b. 一个类有什么方法 就去分析这个类有什么功能.

#pragma mark - Day03_03_对象作为类的属性(较难)

对象可以作为类的属性

1)属性的本质是变量.

在创建对象的时候,对象中的属性是按照类模板中的规定挨个挨个的创建出来的.

类模板中属性是什么类型.那么对象中的属性就是什么类型.

如果对象的属性是另外1个类的对象,这个属性仅仅是1个指针变量而已.并没有对象产生.

这个时候 还要为这个属性赋值1个对象的地址 才可以正常使用.

2) A类可以作为B类的属性. 代表B拥有A.

属性仅仅是1个变量而已. 是1个指针变量而已.默认值是nil 并没有创建对象.

这个时候如果你要正常的使用的话. 还要为B对象的A属性赋值1个对象.

#pragma mark - Day03_04_玩家类的设计

练习

1.猜拳游戏的流程

1). 玩家出拳.

2). 机器人出拳.

3). 裁判宣布比赛结果.

2. 面向对象的重点在于找类.

玩家类:

属性:姓名、选择的拳头、得分.

方法:出拳 -> 自行选择1个拳头来出.

机器人类:

属性:姓名、选择的拳头、得分.

方法:出拳. -> 随机出拳

1) 枚举或者结构体定义在什么地方.

如果只是1个类要用.那么就定义在这个类的头文件中.

如果多个类要用.那么就定义在1个单独的头文件中.谁要用 谁就去引就可以了

2) 如果要在方法中调用当前对象的另外1个方法.

[self 方法名];

self代表当前对象.

/**

*  玩家类:代表1个玩家.

*/

@interface MKPlayer : NSObject

{

@public

/**

*  玩家对象的姓名

*/

NSString *_name;

/**

*  玩家对象的得分.

*/

int _score;

/**

*  玩家对象选择的拳头.

*/

MKFistType _selectedType;

}

/**

*  出拳的方法.

*/

- (void)showFist;

/**

*  根据传入的整型的数返回对应字符串拳头

*

*  @param numebr 整型的数

*

*  @return 对应的拳头类型.

*/

- (NSString *)fistTypeWithNumber:(int)numebr;

@end

@implementation MKPlayer

/**

*  出拳的方法.

*/

- (void)showFist

{

//1. 先提示用户选择拳头.

NSLog(@"亲爱的玩家[%@]请选择你要出的拳头 1.剪刀 2.石头 3.布",_name);

//2. 接收用户输入拳头

int userSelect = 0;

scanf("%d",&userSelect);

//3. 显示用户选择拳头

//   要取出整型的数代表的字符串的拳头的类型.

NSString *type =  [self fistTypeWithNumber:userSelect];

NSLog(@"玩家[%@]出的拳头是:%@",_name,type);

//4. 将用户选择的拳头存储在当前对象的属性中.

_selectedType = userSelect;

}

/**

*  根据传入的整型的数返回对应字符串拳头

*

*  @param numebr 整型的数

*

*  @return 对应的拳头类型.

*/

- (NSString *)fistTypeWithNumber:(int)numebr

{

switch (numebr)

{

case 1:

return @"剪刀";

case 2:

return @"石头";

default:

return @"布";

}

}

@end

1) 枚举或者结构体定义在什么地方.

如果只是1个类要用.那么就定义在这个类的头文件中.

如果多个类要用.那么就定义在1个单独的头文件中.谁要用 谁就去引就可以了

2) 如果要在方法中调用当前对象的另外1个方法.

[self 方法名];

self代表当前对象.

#pragma mark - Day03_05_机器人类的设计

机器人类的设计

/**

*  机器人类

*/

@interface HMRobot : NSObject

{

@public

/**

*  机器人对象的姓名

*/

NSString *_name;

/**

*  机器人选择的拳头

*/

MKFistType _selectedType;

/**

*  机器人对象的得分.

*/

int _score;

}

/**

*  机器人出拳的方法.

*/

- (void)showFist;

/**

*  根据传入的整型的数返回对应字符串拳头

*

*  @param numebr 整型的数

*

*  @return 对应的拳头类型.

*/

- (NSString *)fistTypeWithNumber:(int)numebr;

@end

@implementation MKRobot

/**

*  机器人出拳的方法.

*/

- (void)showFist

{

//1. 随机出拳.

int robotSelect = arc4random_uniform(3)+1;

//2. 显示随机出的拳头.

NSString *type =  [selffistTypeWithNumber:robotSelect];

NSLog(@"机器人[%@]出的拳头是:%@",_name,type);

//3. 将出的拳头保存在当前对象的属性中.

_selectedType = robotSelect;

}

/**

*  根据传入的整型的数返回对应字符串拳头

*

*  @param numebr 整型的数

*

*  @return 对应的拳头类型.

*/

- (NSString *)fistTypeWithNumber:(int)numebr

{

switch (numebr)

{

case 1:

return @"剪刀";

case 2:

return @"石头";

default:

return @"布";

}

}

@end

#pragma mark - Day03_06_猜拳游戏结束

裁判类的设计

/*

机器人类

属性:姓名、选择的拳头、得分.

方法:出拳. -> 随机出拳

*/

#import <Foundation/Foundation.h>

#import "MKFistType.h"

@interface MKRobot : NSObject

{

@public

/**

*  机器人对象的姓名

*/

NSString *_name;

/**

*  机器人选择的拳头

*/

MKFistType _selectedType;

/**

*  机器人对象的得分.

*/

int _score;

}

/**

*  机器人出拳的方法.

*/

- (void)showFist;

/**

*  根据传入的整型的数返回对应字符串拳头

*

*  @param numebr 整型的数

*

*  @return 对应的拳头类型.

*/

- (NSString *)fistTypeWithNumber:(int)numebr;

@end

@implementation MKRobot

/**

*  机器人出拳的方法.

*/

- (void)showFist

{

//1. 随机出拳.

int robotSelect = arc4random_uniform(3)+1;

//2. 显示随机出的拳头.

NSString *type =  [self fistTypeWithNumber:robotSelect];

NSLog(@"机器人[%@]出的拳头是:%@",_name,type);

//3. 将出的拳头保存在当前对象的属性中.

_selectedType = robotSelect;

}

/**

*  根据传入的整型的数返回对应字符串拳头

*

*  @param numebr 整型的数

*

*  @return 对应的拳头类型.

*/

- (NSString *)fistTypeWithNumber:(int)numebr

{

switch (numebr)

{

case 1:

return @"剪刀";

case 2:

return @"石头";

default:

return @"布";

}

}

@end

#pragma mark - Day03_07_如何取到当前对象的属性

1) 类中的方法的参数,可以使用当前类的对象作为参数

2) 类中的属性,可以使用当前类的对象作为属性

#pragma mark - Day03_08_异常处理

1) 错误:

1). 一般情况下,指的是我们的程序的源代码有语法错误.

2). 错误的后果: 无法编译 更谈不上执行.

2). 解决方案: 将错误的代码修改为符合语法规范的代码不就OK了

2) BUG

1. 指的是,程序可以编译、链接、执行. 只不过程序执行出来的结果并不是我们所预设的那样.

2. 解决方案: 99%的Bug都是因为变量的值没有按照我们所预想的那样去变化.

3) 异常

1.概念: 指的是,程序可以编译、链接、执行.

当程序在运行的时候,程序处于某种特殊情况下的时候 程序的执行就会报错,这种情况我们叫做异常.

2.特点: 异常不是一定会发生.而是当程序在运行的时候处于某种特定情况的时候才会发生.

3.后果: 程序立即终止运行.后面的代码不会执行.

闪退的原因:

a. 程序所占用的空间太大.

b. 程序发生了异常

.....

4) 异常的处理.'

1. 处理异常的目的: 希望程序在执行的时候,如果发生了异常. 程序不要崩溃,而是继续往下执行代码.

2. 使用@try...@catch处理异常.

3. 将有可能发生异常的代码使用@try围起来.

4.作用: 让代码在执行的时候如果发生了异常 而不崩溃.

5. 使用注意

1. 在@try中的代码执行的时候,如果发生了异常.

会将发生异常的信息.封装为1个 NSException 对象, 把这个对象的地址,赋值给@catch的参数,然后再执行@catch的代码.        所以,@catch的参数指向了错误对象,在@catch中如果想要拿到发生异常的原因.就可以访问这个参数对象.

2. @catch中的代码只有在发生异常的时候,才会执行.

所以.@catch中一般我们写处理异常的代码.

3. @catch后面还可以跟1个@finally代码块.

无论@try中是否有异常发生.@finally中的代码都会被执行 .

4. @try..@catch并不是万能的 不是所有的异常都可以处理.

C语言的异常处理不了. 只能处理OC的异常.

5. @try..@catch在我们的代码中很少使用.

我们一般情况下都是 通过逻辑判断来减少异常的发生.

#pragma mark - Day03_09_类方法的基本使用

1. OC中的方法分两种.

-> 对象方法/实例方法:  我们之前学习到的方法就叫做对象方法.

对象方法必须使用对象名来调用.

也就是说,想要去调用对象方法 就必须要创建1个对象.

-> 类方法:  类方法的调用不依赖于对象,而是依赖于类.

要调用类方法 不需要创建对象 而是直接通过类名就可以调用.

2. 声明

1). 对象方法的声明使用一个 - 号

- (void)sayHi;

2). 类方法的声明使用一个 + 号.

+ (void)classMethod;

3. 调用

1). 要调用对象方法就必须要创建1个对象,通过对象名来调用.

[对象名 对象方法名];

2). 要调用类方法,不需要创建对象. 直接使用类名可以调用.

[类名 类方法名];

需要注意的是. 对象方法只能通过对象名来调用.

类方法只能通过类名来调用.

3. 类方法的特点:

1). 节约空间: 因为类方法的调用不需要创建对象.

而对象方法的调用还要首先创建1个对象.

2). 提高效率: 类方法的调用.直接找到代码区中的类,找到类中的类方法执行.

对象方法要先通过指针找到对象,再通过对象的isa指针找到类.再找到类中的方法执行.

4. 类方法的局限性

在类方法中无法直接访问类的属性.

也不能通过self关键字去调用当前类的对象方法.

因为类方法的调用不需要创建对象的. 而属性只有对象创建了以后才有.

所以,类方法在执行的时候,对象有可能还没有呢.对象都没有 如何访问属性呢?

同样的原理;在类方法执行的时候,还没有对象,而对象方法的调用必须要依赖于对象来调用.

所以.在类方法中不能直接使用self调用当前类的.对象方法.

5. 什么时候,我们需要将方法定义为类方法呢?

如果我们的方法不需要访问属性.也不需要直接调用当前类中的对象方法.

那么就可以将这个方法定义为类方法,来节约空间提高效率.

#pragma mark - Day03_10_使用类方法需要注意的问题

1). 对象方法之间是不能重名的.

2). 类方法之间也是不能重名的.

3). 类方法和对象方法可以同名.

如果通过类名来调用,那么调用的就是类方法.

如果通过对象来调用,那么调用的就是对象方法.

4). 对象方法只能通过对象来调用.

类方法只能通过类来调用.

5). 类方法中虽然不能直接访问属性和调用对象方法

但是.可以创建1个对象,访问这个对象的属性和对象方法.

6). 类方法中不能直接调用当前类的对象方法.除非创建1个对象,通过这个创建的对象调用.

在对象方法中可以直接使用类名来调用类方法.

#pragma mark - Day03_11_类方法的规范

1. 我们写1个类 就要为这个类提供1个和类名同名的类方法.这个类方法来返回1个纯洁的对象.

纯洁的对象: 对象的属性的值都是默认值.

+ (MKPerson *)person

{

MKPerson *p1 = [MKPerson new];

return p1;

}

2. 如果希望创建出来的对象的属性的值是由创建者指定的.

那么这个时候,就可以为这个类方法带参数. 在方法内部创建对象. 并初始化对象的属性.

返回.

+ (MKPerson *)personWithName:(NSString *)name andAge:(int)age

{

MKPerson *p1 = [MKPerson new];

p1->_name = name;

p1->_age = age;

return p1;

}

#pragma mark - Day03_12_new其实是1个类方法

对象的创建.

MKPerson *p1 = [MKPerson new];

new其实是1个类方法.

做的事情: 创建对象、初始化对象.

返回值: 返回创建的这个对象的地址.

#pragma mark - Day03_13_NSString的本质是1个类

1) NSString是1个数据类型,用来保存OC字符串的.

2) 实际上. NSString应该是1个类.

既然是1个类.所以,完整的创建NSString对象的方式应该是这样的

NSString *str0 = [NSString new];

NSString *str1 = [NSString string];

因为NSString是OC中最常用的1个对象.如果每次都这么创建字符串对象的话,就太累了.所以,苹果就提供了1种快捷的方式来创建1个NSString对象.

@"jack"  这个本质上是1个NSString对象. 这是苹果提供的一种简写方式.

@"rose"  是1个NSString对象.这是1个创建NSString对象的简写方法.

NSString对象是来保存字符串的.

1. 要存储字符串的完整的方式.

a. 先创建NSString对象.

b. 把字符串存储到这个对象中.

2. 但是这么做太麻烦了. 所以,苹果提供了一个简写的方式,使用@符号.

@"jack" ;  创建1个NSString对象,然后把字符串"jack"存储到这个对象中去.

%p: 代表打印指针变量的值.只不过这个指针变量的值是1个地址.

%@: 代表打印指针指向的对象.

NSString *str = [NSString new];

这种方式创建的字符串是1个空字符串  @""  不是nil

#pragma mark - Day03_14_NSString的常用方法

1) 常用的类方法.

a. 将C语言的字符串转换为OC字符串对象.

+ (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;

nullable: 代表返回的对象有可能是nil

b. 将变量拼接成1个新的OC字符串.

+ (instancetype)stringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);

2) 常用的对象方法.

a. 得到字符串的长度.

- (NSUInteger)length;

NSUInteger 这货其实就是unsigned long

b. 得到指定下标的字符.

- (unichar)characterAtIndex:(NSUInteger)index;

在OC语言中 1个中文占据2个字节.

返回值是unichar 占据2个字节.

OC字符串中的字符 如果是英文字符占据1个字节 .如果是中文字符就占据2个字节.

打印unichar字符使用%C  这是大C

c. 判断两个字符串的内容是否相同.

如果要判断两个字符串的内容是否相同.不要使用==来判断.会出问题.

- (NSComparisonResult)compare:(NSString *)string;

返回的是1个枚举值.

NSOrderedAscending : 当前字符串比传入的字符串小.   升序 123 左边(对象) < 右边 (传进来的字符串)

NSOrderedSame:  一样

NSOrderedDescending 当前字符串比传入的字符串大     降序 321 左边(对象) > 右边 (传进来的字符串)

如果枚举记不住,用整型就可以了.

d. 只判断两个字符串是否相同.;

- (BOOL)isEqualToString:(NSString *)aString;

"作业

1) 设计类

狗类

属性: 名字,年龄

对象方法:

叫几声

类方法:

1.快速创建类方法

2.快速创建类,并设置属性方法.

车类

属性: 品牌,公里数

对象方法:

给车一个速度,车开动,并且公里数增加

类方法:

1.快速创建类方法

2.快速创建类,并设置属性方法.

人类

属性: 姓名,年龄,狗,父亲

对象方法:

1.给他一辆车,让车跑

2.遛狗

类方法:

1.快速创建类方法

2.快速创建类,并设置属性方法(除去'父亲').

3.给他两个人对象(儿子,父亲),判断这两个人对象是不是父子关系

需求:

1. 用普通方式创建一条狗对象(d1),并设置d1的属性

2. 用普通方式创建一个人的对象(p1),并且设置属性,把d1赋值给p1的狗属性,然后遛狗

3. 用类方法创建一个车对象(car),然后让p1开车

4. 用类方法创建一个人对象(p2),并把p2赋值给p1的父亲

5. 用类方法创建一个狗,并设置属性,赋值给p2,然后通过p1打印出这条狗的名字

6. 调用人类的类方法,判断 p2 是不是 p1 的父亲

2) 字符串练习

1. 使用三种方式创建一个'值为空'的字符串(!nil)

2. 使用两种方式创一个值为'xiaoming'的字符串

3. 打印 @"123456778900987654321"的长度

4. 把这三个字符串(@"123"  @"cvb"  @"你好,世界!")拼接到一起,并打印

5. 比较 @"abc"  和 @"abd" 的大小

6. 判断 @"abcdefg" 和 @"abCdefg" 存的值是否相等

7. 获取 @"我英文不好a" 第5个字符的值

上一篇:POJ 2965 The Pilots Brothers' refrigerator


下一篇:Event事件的兼容性(转)