Objective-C基础教程1-6章节
最近不算很忙,又没有太多深入研究,按照惯例找一些没接触过的新东西看看学习学习,WiEngine,Box2d之后,这次轮到了Objective-C。Objectvie-C随着苹果设备的风靡,也是最热门的技术之一,无奈之前对C一直存在一些芥蒂,所以没有去接触,不过怎么说语言也是共通的,有些坎肯定还是要迈过的,特别是当下所谓跨Android/iPhone平台,其实都是用C++在开发,所以上上手也是很有必要。
下面是对看Objective-C基础教程1-6章后,对一些东西的笔记,并不是完整的教程,只是类似拾遗,将一些不同的,不熟悉的东西记下来(和之前Python笔记类似)
一切都源于Hello World 恒古不变的定律,熟悉一门语言结构最快也就是这个万能的程序了,Objective-C扩展名为.m(之后书中也有提到.mm就是C++风格)
其中NSLog方法是Objective-C专属的一种类型,所有cocoa的对象都被冠以了NS前缀,作为区分。传入的参数@""表示字符串作为NSString被处理,程序其余部分和C类似,#import的含义也不言而喻
布尔值
Objective-C中的布尔变量有些许小的不同,参数类型为BOOL,值为YES/NO,其中YES为1,NO为0,占8位
需要注意的是,如果将一个int,short这样的值赋给BOOL,只有低位字节会发挥作用,这是特别要注意的,因为这意味着,并不是传统认为的,非零即为true
Objective-C中有一种特有的语法:[对象 操作] 这在之后会一直看到
关于Objective-C中的OOP
@interface
至少目前我还将其于java中的接口相类比,名称也一样,但是有人告诉我Objective-C中的interface并不同于接口,而类似于接口的Objective-C中有一个叫做协议的东西,这个以后看到了我会再加以对比区分
以上就是标准的一个@interface定义,应该很好理解,Circle含有2个变量color,bounds,拥有3个方法
特别注意方法的申明方式
(void) 表示返回类型 之后是方法名及参数
draw方法不含参数 也不用:
对于多个参数的方法申明
-(void) setTire: (Tire *) tire atIndex:(int) index;(这里的第二个参数看起来有些奇怪,但是在之后调用方法的过程中,atIndex会被用到)
Objective-C的方法调用使用了一种被称为中缀符的东西
看一下分别调用无参,1参和多参的语法
@implementation
与名字相同,实现,就是对@interface所申明内容的具体实现
这里的color=c其实就相当于self.color=c(这里我又要做类比了,目前的认识self就相当于java中的this指针)
有了@interface和@implementation之后,我们对一个类(对象)的定义就算完成,那么如何实例化一个对象呢
这里又看到一个新的东西id,它是一种指向某个对象的指针,目前为止只是看到这一种用法,也没有太多认识,简单的被我理解成了索引
之后看到了new对象的方法[Circle new],再之后是调用对象的方法设置具体的参数
继承
很简单的方法,Objective-C在继承规则上于java,C#无异,不允许多重继承,不过既然有接口(或者应该叫协议),那么自然同java一样,达到相同的目的自然不难,同样的,子类可以调用父类的方法,通过super,比如[super setColor:c];
Ojbective-C中的空值为nil
接下来 来看一个Car是被如何自动构建的
这一段有些理解不能,在书中的注释中说到,这里指如果超类可以完成所需的一次性初始化,需要调用[super init]。init方法的返回值id描述了倍初始化的对象。将[super init]的结果赋给self是Objective-C的标准惯例。
Objective-C中一样有getter/setter方法,但是在命名规则上需要注意
在set方法中 依然采取setXXX的方式 但是get方法则直接采用XXX 而非getXXX,以免混淆
拆分
一般将@interface部分放入.h文件中
将其他部分放在.m中,在.m中记得引入该头文件
#import "Tire.h"
import下<>代表系统头文件 ""代表本地头文件
关键词@class 告诉编译器此处是一个类,还需要通过指针进行传递
注意这只有在通过指针指向其他类的情况下可用,减少编译器负担,在继承的情况下不可用,因为他需要了解超类的信息
----------------------------------------------
Foundation Kit
Cocoa由两个不同的框架组成 Foundation Kit和Application Kit
Foundation框架中有很多诸如NSString,NSArray等低级类和数据类型
通过alloc创建并通过init初始化了一个池,在结尾处排空,这是Cocoa内存管理的预览
一些有用的数据类型
范围 NSRange
表示相关事物的范围,如字符串中的字符范围或数组中的元素范围
创建一个新的NSRange有3种方式
第三种方法的好处是可以在任何能够使用函数的地方使用,比如当作参数
几何数据类型 NSPoint,NSSize
比如Cocoa提供了矩形数据类型
同样提供了NSMakePoint(),NSMakeSize(),NSMakeRect()方法
将这些数据类型作为struct而不是对象的好处是性能更高
字符串 NSString
创建字符串
类方法
我们所创建的大部分方法是实例方法 用前导减号 - 声明
如果方法用于实现常规功能,用前导加好 + 来声明类方法
就如NSString的stringWithFormat方法
关于大小
使用方式
该方法可以正确处理国际字符串
比较
使用方式
同样的compare方法
返回一个NSComparisonResult枚举类型
如果返回NSOrderedAscending 表示左侧小于右侧 其他类似
不区分大小写的比较
options参数是一个掩码
NSCaseInsensitiveSearch 不区分大小写
NSLiteralSearch 完全比较,区分大小写
NSNumericSearch 比较字符个数而不是字符值 比如100应该排在99以后
判断字符串内是否包含其他字符串
分别检查以特定字符串开头和结尾
返回匹配的位置,如果找不到 则range.start=NSNotFound
可变性
NSString是不可变的
NSMutableString是可变字符串
两者间比较类似Java中的String和StringBuffer
创建NSMutableString的方法
该容量只是一个建议
可以使用一些方法操作该string
使用起来非常方便 也很显而易见
类似的
删除字符串中的字符
NSMutableString是NSString的子类,所以可以使用NSString的所有功能
因此同样可以使用stringWithFormat来创建NSMutableString
集合家族 NSArray NSDictionary等
NSArray可以放入任意类型的对象
两个限制:
1 只能存储Objective-C对象,而不能是C基础类型int,float,enum,struct等
2 不能存储零值nil NULL值
可以通过类方法arrayWithObjects创建,以逗号分割对象列表,并最后以nil表示列表结束
获得对象个数
取得特定索引处对象
例如遍历一个数组
将字符串切分成数组
将数组合并成字符串
可变数组
NSArray是不可变的,类似的NSMutableArray可变
创建新的可变数组
在数组末尾添加对象
删除特定位置对象
枚举 NSEnumerator
通过objectEnumerator向数组请求枚举器
这似乎类似于Java的迭代器Iterator
使用
可以从后向前浏览集合 reverseObjectEnumerator
请求下一个对象
当返回nil时表示结束
快速枚举
NSDictionary 有些类似于Map(散列表,关联数组)
类似的NSDictionary不可变,可变的NSMutableDictionary
创建字典的方法
例如
使用objectForKey来获取值
例如查找右后轮胎
同样的,对于可变的字典
为可变字典添加元素
如果当前已有值,则新值会替代原有的值
删除值
使用但不扩展
不要自己去创建NSString,NSArray,NSDictionary的子类
各种数值
就和Java中对int,float等有Integer,Float等对象封装,Objectvie-C也提供了NSNumber的包装类
类似的还有long,long long等
例如将一个包装后的数据放入数组
从包装类获取值
等
NSValue
NSNumber是NSValue的子类,NSValue可以包装任意值
例如,将NSRect放入NSArray
这里使用@encode编译器指令,它可以接受数据类型的名称并转化为合适的字符串
使用getValue取值
传递的是存储该数值的变量地址
Cocoa提供了常用的将struct型数据转换成NSValue的方法
例如,在NSArray中存储和检索NSRect
NSNull
之前提到nil在NSArray和NSDictionary中有特殊的含义,所以不能把nil放入其中,如果要真的表示没有,Objectvie-C提供了NSNull
使用[NSNull null]==来比较是否为空
--------------------------------------------------------
完全是按照书上章节的顺序来的 这次是第九章的内容 关于内存管理
作为一名一直写java,当初就是因为java的自动垃圾回收机制,于是偷懒投奔java阵营的来说,这次不得不又回过头来面对这个问题了。后面的笔记只是对书中一些内容的记录总结,由于没有实战,具体使用中会碰到什么问题还是不得而知,而且我想那一定会存在相当多的问题,好在最后给出的三条准则还是非常易用的。(听同伴说xCode提供了检查内存泄露的工具,挺好用)
本章最后提到了Objective-C也同样可以打开垃圾回收,不过由于只对高版本有效,并非通用,所以个人感觉既然使用了Objective-C,因此还是应该掌握内存管理的方法。
对象的声明周期:
诞生(通过alloc或new)、实现(接收消息和执行操作)、交友(借助方法的组合和参数)、死去(被释放)
Cocoa使用引用计数
当使用alloc,new或者copy方法创建一个对象时,计数器值设为1
发送retain消息增加计数器值,减少使用release
当计数器归0,Objective-C自动发送dealloc消息,可以重写dealloc方法,但是不要直接去调用该方法
发送retainCount消息获得当前计数器值
表示要求car对象将计数器加1,并执行setTire操作
一种set方法的正确内存管理方法
自动释放池
NSObject类提供了autorelease方法
执行后对象将被添加到自动释放池中,自动释放池被销毁时,向其中所有对象发送release消息
Cocoa内存管理规则
* 当使用new,alloc,copy方法创建一个对象时,该对象保留计数器为1,如果不再使用该对象,需要手动发送release或autorelease消息
* 通过其他方式获得的对象,则假设该对象计数器为1,并以设置自动释放,不需要做任何事,如果需要在一段时间内使用,那么保留该对象并确保在工作完成后释放
* 如果保留了某个对象,最终需要手动释放该对象,保持retain和release使用次数相等
例如
临时对象
使用了alloc获得对象,所以用完需要释放
注意这里使用了arrayWithCapacity获得对象,并不是3者之一,所以无需做任何事
和上述情况相同,其实这里的blueColor是一个全局单例对象,永远不会被销毁
拥有对象