这一节课中讲得都是一些很基础的东西,从objective-C的一些简单的知识到Foundation框架中的各个对象的使用。
objective-C 知识
创建对象
alloc init方法
一般情况下,我们使用alloc init方法进行对象的创建,比如:
|
|
使用类方法创建
还有一些是使用类方法来创建,比如:
|
|
alloc init方法&类方法
还有一些是既有alloc init方法,又有类方法的,比如format
方法
既有
|
|
又有
|
|
他们的作用完全相同。他们同时存在算是一种历史遗留问题。
通过另一个方法来创建
比如NSString中的
|
|
你发送一个字符串给他,他会创建一个新的字符串返回给你。
nil
nil表示不指向任何东西,我们可以向nil发送消息,程序不会发生崩溃,但是也不会发生任何事情。
动态绑定
动态绑定中有一个很重要的东西叫做 id,id是一个指针,所以不存在*id。它指向未知或者未指定对象。实际上oc中所有的指针都是id。但是id类型如果使用不当就会照成程序崩溃。接下来我们来说明一下。
|
|
上边这行代码很清楚的说明了编译器想要的东西,s的类型,他的值是多少。
|
|
而这一行就有些危险,他声明了一个id类型的obj并指向了字符串类型s。
|
|
这时候我们让一个数组类型的变量指向了字符串类型,这样就非常危险了。很有可能发生崩溃。
为了理解的更充分一点,我们来举一个例子:
我们现在有两个类,一个类Vehicle
(交通工具),他有一个方法move
(运动)。还有一个类Ship
(船),他继承于Vehicle
,所以他也可以实现move
方法,而且他自身还有一个shoot
(射击)方法。
|
|
现在我声明一个局部变量,一条船s。这时候我执行shoot让船射击,或者执行move让船移动都没有任何的问题。
|
|
我还可以声明一个交通工具v,让他指向s,这也没问题,因为船是交通工具的一种。
|
|
那现在我让v执行shoot射击,这时候编译器会发出警告,因为Vehicle没有shoot方法。但是运行时,他不会崩溃,因为我们知道v是一艘船,所以不会崩溃。
|
|
接下来我声明一个id类型的obj,不指定obj是个什么东西。然后我让他执行shoot射击,这时候,编译器不会提醒你有错误,因为我们确实有一个shoot方法,而且obj不知道是个什么东西,所以不会报错。但是在运行时,因为obj中没有shoot这个方法,所以这时候程序就会发生崩溃。
|
|
但是如果我现在让obj执行一个不存在的方法时,编译器就会报错,因为编译器会觉得我可能是写错了?拼写出了问题,所以这时候编译器就会提示。
|
|
那接下来我们继续假设,有一个NSString类型的hello,我让他执行shoot操作,那运行时肯定会崩溃,因为我们指定了hello就是字符串类型的,而字符串并没有设计这个操作,那么一定会崩溃。而且编译器也会对我们发出警告。
|
|
那么如果现在我使用强制转换类型创建一个helloShip,这时候编辑器会认为helloShip是一个ship,但是我们明白,他是一个字符串,这个时候我们如果让helloShip执行shoot方法时,编译器不会报错,因为他认为helloShip是ship,有shoot方法。但是在运行时,程序会发生崩溃。因为字符串类型不会对shoot方法进行反应。
|
|
这种情况下我们的代码就会非常危险,如果一个不注意就会发生崩溃,那么如何避免这样的问题,我们就要用到类型保护机制,我们可以使用内省或者协议来对我们的类型进行保护。
类型保护机制(内省)
isKindOfClass
他可以让你问一个NSObject对象或者继承于NSObjet类的对象,是否属于这一系列类。isMemberOfClass
他与isKindOfClass
差不多,他是用来确定你是否实际是这个类。respondsToSelector
他是说id指向的这一对象,是否能对某一个特定的方法做出反应,比如船是否可以执行射击操作。
内省经常用于MVC中的通信和从数组中选择一个东西出来的时候的判断。
比如:
这段代码就非常不安全,如果otherCards
中存在不能响应play
方法的时候,就会照成程序的崩溃。
|
|
添加了类型保护机制之后就不会出现这样的问题了,这时候通过isKindOfClass确认之后。我们给card发送消息的时候,就不会发生崩溃了。
|
|
Foundation
Foundtion这里并没有讲太多东西,都是一些基础的数据类型,所以这里也就不详细写出来了。
NSObject
所有的类都继承于NSObject,他有一个很重要的方法
|
|
当我们使用NSLog的时候,就会调用到description
函数。
NSArray
不可变数组。可以使用@[]方法创建新的数组。
NSMutableArray
可变数组,能够使用NSArray中的所有方法,并且可以添加和移除数组里的元素。
NSNumber
用于存放所有原始类型,整形、浮点型、布尔类型等等。可以直接使用 @3 这种格式来声明。
NSDara
二进制文件
NSDate
日期相关的东西会使用到这个,还可以使用NSCalendar
来处理日历,NSDateFormatter
来处理日期格式,还有NSDateComponets
。
NSDictionary
字典,仅次于数组的最重要的一种类型。由键值对组成。
NSMutableDictionary
可变字典,与数组和可变数组的关系一样,可以使用字典的所有功能,并且可以添加删除元素。
NSUserDefaults
他是一种共享字典,在程序里一直可以保存,但是他不能保存很大的东西,比如图片啊什么的,他可以存储一些字符串或者数字等一些小东西。
在设置完数据之后一定要记得使用synchronize
来同步,如果不同步的话,之前设置的内容在程序杀掉之后就不会存在了,所以一定要记得使用synchronize
同步数据。
NSRange
用来表示一个范围,他是一个结构体,用来表示一个起始位置和长度。
|
|
Fonts 字体
这里提到,如果你只会使用一种设置字体的方法,那么一定就是这个方法:
|
|
后边的参数有很多种,可以根据使用的场景选择不同的字体类型。
并且还说明了最好不要使用系统字体来设置字体。
NSAttributedString
这是一个神奇的字符串,你可以对他进行很多设置,但是要记住,这个字符串的内容是不可变的。可以通过NSRange
来对部分字符串进行修改。
这个类的具体使用会在下一节课中写一个Demo来着重讲解。所以这里就先不多啰嗦,等到下节课的笔记中再详细介绍如何使用它。