《Objective-C基础教程》
0. 杂问杂记
Q:与C语言特性的关系,可直接使用所有C特性吗?
A:Objective-C只是”增强"了C,所有保留了所有C的属性。 YES !
Q:向nil(空)对象发送消息,不会出现异常,表示停止操作命令???
A: I guess 没有问题,这是和Java/C++最大不同之一。 2011/12/21
Q:委托与数据源到底是什么东东???
Q:感觉release使用很频繁?
Q:如果iPhone叫不使用autorlease,NSString一些对象如何管理的?
Q:setter方法中,使用“retain新对象,release老对象”感觉太复杂?
T:一篇关于NSObject的文章:http://www.cnblogs.com/yaski/archive/2009/04/13/1434308.html
Q:dealloc()方法总是会被自动调用,而init()不会?
Q:保留retain周期?
Q:如果代码完全不使用NSAutoreleasePool,是否会有问题?
1. Chap 9 内存管理
* 引用计数器
new/alloc/copy=1
retain+1
release-1
当计数为0,dealloc自动被调用(相当于C++的Deconstructor)
* NSAutoreleasePool
## 使用
int main(...) {
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
...
[pool release];
...
}
注:
#1 pool以全局stack方式管理,所有autorelease都针对顶部pool进行。
* set方法:内存管理实例
-(void) setEngine: (Engine *)newEngine {
[newEngine retain];
[engine release];
engine=newEneing;
}
注:retain新对象,释放老对象。
Q:这样做,对于普通的setter方法实在太复杂???
A:所以出现了@property
* 内存管理三原则
#1 new/aclloc/copy获取对象,必须在自己的代码中使用release/autorelease进行处理
#2 其它方式获得的对象,可以假设:其引用计数为1,并且已经加入autorelease pool
#3 retain/release使用次数必须对等?
注1:总之,自己生成的新对象自己管理,别的对象假设已经被管理好了。
注2:特别注意对象之间不要循环“引用”,否则,两个对象永远不释放。一般原则是Owner引用其它对象,而不是相反。
* 垃圾回收GC:类似于Java中的GC
-fobjecc -gc
注1:iPhone开发需要谨慎使用autorelease
注2:iPhone中不使用GC ?
2. chap 10 对象初始化
* 对象生成
分两步:分配内存,初始化
两种方式:
[Class new]
[[Class alloc] init]]
^ 此init定义在NSObject中,对相关内存区域清0
注1:通常使用init方式,原因目前暂不明白?
Q:WHY ? 2011/12/21
注2:init()是一普通函数,不会自动被调用,这和Java/C++的构造函数不同!
A:直接使用[ClassName new]的时候,init()不会被调用,对吧? 2011/12/21
* init()函数
-(id)init {
if(self=[super init]) {
...
}
return(self);
}
3. Chap 11. 特性 property
* 意图
以预编译的形式来自动生成setter/getter函数,并在需要的时候处理对象的retain/release问题
YES! That's very useful !!!
Q:可以自定义其实现方式?
* 定义与实现
@property(readwrite, copy) NSString *shoeSize;
@synthesize shoeSize;
注:变量名与property名可以不同。
* 点表达式:类似Java,但一些细节上不完全相同。
只是对相关方法调用的一种“快捷”书写方式
例:
self.name=@"Car"; =====> [self setName: @"Car"];
注1:若setName不存在,则错误
注2:name并不是一个类中的属性,而是一个property,所以,类中的真正属性不一定是name
* 特性property本身的属性
Q:对象内存管理(retain, assign, copy)
是否只读(readwrite, readonly)
4. Chap 12 类别Category
* 目的
给类“动态”增加新的功能,不过不能增加新属性
* 声明与使用
@interface NSString(NumberConvenience)
^ 类名 ^ Category名
-(NSNumber *)lengthAsNumber;
@end
@Implementation NSString(NumberConvenience)
-(NSNumber *) lengthAsNumber {
unsigned int length = [self length];
return ([NSNumber numberWithUnsignedInt: length]);
}
注:类别影响是全局性的,上例中所有NSString都可以处理lengthAsNumber()消息。
* 类别应用
# 将类实现分散到不同文件,便于控制
# 可为任意类增加新的接口,实现所谓”非正式协议“ protocol
* 委托与类别
Q:P183 ???
5. Chap 13 协议 protocol
* 概念
就是Java的接口(interface)
与Java不同的是,Objective-C 2.0有@optional与@required之分,增加了一些灵活性。
* 申明与使用
@protocol NSCopying
-(id)copyWithZone: (NSZone *)zone;
@end
@interface Car: NSObject <NSCopying, ...>
{
...
}
@end
* 实例:实现CarParts的copy功能
* 协议与数据类型
-(void) setObjectValue: (id<NSCopying>) obj;
^ 若对象未实现NSCopying,则编译出错。Q:神马东东?2011/12/21
Q:鼓励面向protocol编程吗?
6. Chap 15 文件加载与保存 Q:需要好好温习 2011/12/21
* 属性列表对象plist
NSArray, NSDictionary, NSString, NSNumber, NSDate, NSData
*保存与加载
[nsdata writeToFile:@"myfile" automically:YES];
* 自定义序列化与反序列化
@protocol NSCoding
-(void)encodeWithCoder: (NSCoder *)aCoder;
-(void)initWithCoder:(NSCoder *)aDecoder;
@end // NSCoding
* 实现类
NSKeyedArchiver
NSKeyedUnarchiver
* 保存实例:
@interface ArchievableThing : NSObject <NSCoding>
@end
ArchievableThing * thing ...
NSData *freezeDired;
freezeDired = [NSKeyedArchiver archiverdDataWithRootObject: thing];
[freezeDired writeToFile: @"myFile" automically:YES];
注:将对象变成NSData,再使用NSData的函数保存
7. 附录:从其它语言转向Objective-C
* C语言
Objective-C=old C+OO feature
可以使用标准C的所有库,如malloc()/free(), fopen/fclose()等等
* C++语言
#1 C++专属特性
多重继承、命名空间、运算符重载、模板、类变量、抽象类、标准模板库
某些特性Objective-C可模拟
Objective-C有以下特性极有用:
@property
@protocol
catogory
#2 C++虚拟表 vs. Objective-C动态语言特性
C++
VTable,执行快,但因此缺乏动态语言的特性
Objective-C:
任意对象可以成为其它对象的数据源或委托Delegate?,缺乏类型安全性
有元数据,可使用反射
所有对象都动态分配(heap中),不存在stack中的对象
^ 那在stack中还有什么?只有primitive变量和参数? 2011/12/21
没有临时对象的创建与销毁,也不存在对象自动转换
可向nil对象发送消息,不必检查NULL(但结果呢?)
不存在访问控制概念,所有方法都能被其它对象访问,即使不在定义中申明
不存在类变量,但可通过文件范围全局变量模拟
* Objective-C++
混合C++与Objective-C特性,如使用C++的效率与类型安全
* Java语言
Java
interface
类变量
final阻止改变
使用异常
Objective-C
@protocol
无类变量
允许运行时添加方法
使用-1或errorno来处理异,也使用类似于C++的异常机制