iPhone开发进阶 app启动流程

iPhone开发进阶

工欲善其事,必先利其器。在开发iPhone应用程序的时候,深入理解iPhone OS/SDK与Objective-C 2.0是很重要的。

iPhone OS
iPhone OS 由4个主要部分组成。下面简单地罗列一下它们的功能。

Cocoa Touch
窗口和视图
事件管理
用户接口
加速传感器
照相机
Media
Core Graphics(2维图形接口)
Core Animation(动画)
OpenGL
Core Audio(声音)
OpenAL
Media Player(MPEG4,MP3)
Core Services
Address Book
Core Foundation
Core Location
CFNetwork(http,https,ftp,SSL,TLS)
网络安全
SQLite(SQL数据库
XML
Core OS
多线程
网络应用(BSD套接字)
文件系统
Bonjour(利用无线网络连接其他机器)
iPhone SDK
iPhone SDK 中主要包含下列4个工具。

Xcode - 项目管理、代码编辑、编译、调试(IDE)
Interface Builder - GUI 设计
iPhone Simulator - 模拟器
Instrument - 性能测试、调整
实际开发的过程中,基本上是在使用 Xcode 与 Interface Builder 来进行的。调试则是使用模拟器或者实际设备。要注意的是在PC上模拟程序,由于PC的主频,性能高于实际设备,所以不能只在模拟器上调试。除此之外,一些类,功能在模拟器上也是不能使用的,比如 NSDateCalendar 类,或者是照相机功能。

Objective-C 2.0
内存管理
虽然 Objective-C 2.0 已经支持了垃圾收集了,但是 iPhone OS 中却不能使用它。所以我们需要自己来管理内存。Objective-C 的内存管理方式与使用引用计数的方式,就是说对象有一个计数器,引用对象一次,计数器加一,当计数器为0的时候,该对象的内存被释放。

创建对象实例的时候(init,alloc)应用计数加一,执行过程中,别的对象如果需要该对象,需要用(retain)来引用它,这时,该对象的应用计数器加一。不需要对象的时候用(release)来释放,这时引用计数器减一,当计数器为0的时候,释放该对象内存。

init,alloc - 计数器 +1
retain - 计数器 +1
release - 计数器 -1
另外如果不使用 retain,release,可以使用(autorelease)来自动释放对象。

容器
Objective-C 中的容器主要有以下3种:

数组
字典
Set
向容器中添加的内容不能直接用 int 或 float,需要通过 NSNumber 等封装类来实现。Objective-C 2.0 开始可以使用迭代子(Enumerator),来顺序访问容器中的元素。

Notification
Notification是消息通知的功能。具体使用 NSNotificationCenter 类。将需要接受通知的对象,方法,事件注册到该类上。

归档(Archive)
归档是指将对象的内存布局原样地保存到文件系统上。同样对应的由文件中的数据生成对象叫做UnAchive。在 iPhone SDK 中使用 NSKeyedArchiver 和 NSKeyedUnarchiver 类来实现。

一般在程序结束的时候,保存当前的状态,再次启动的时候UnAchive一下,就又回到了刚才退出时的状态。下面是一个例子:

// MyKeyedArchiver.h
#import <Cocoa/Cocoa.h>

@interface NSKeyedArchiver (MyKeyedArchiver)

- (void)encodeValueOfObjCType:(const char *)valueType at:(const void *)address;

@end
#import "MyKeyedArchiver.h"

@implementation NSKeyedArchiver (MyKeyedArchiver)

- (void)encodeValueOfObjCType:(const char *)valueType at:(const void *)address
{
NSMutableData *datas = [NSMutableData data];
NSArchiver *arch = [[NSArchiver alloc] initForWritingWithMutableData:datas];
[arch encodeValueOfObjCType:valueType
at:address];
[self encodeObject:[NSData dataWithData:datas]];
[arch release];
}

@end
// MyKeyedUnarchiver.h
#import <Cocoa/Cocoa.h>

@interface NSKeyedUnarchiver (MyKeyedUnarchiver)

- (void)decodeValueOfObjCType:(const char *)valueType at:(void *)data;

@end
#import "MyKeyedUnarchiver.h"

@implementation NSKeyedUnarchiver (MyKeyedUnarchiver)

- (void)decodeValueOfObjCType:(const char *)valueType at:(void *)data
{
NSData *datas = [self decodeObject];
NSUnarchiver *unarch = [[NSUnarchiver alloc] initForReadingWithData:datas];
[unarch decodeValueOfObjCType:valueType
at:data];
[unarch release];
}

@end



开发iPhone程序,首先接触到的不是源代码,而是项目工程文件,目录。我们来看看它有怎样的构成。

iPhone应用程序目录构成
iPhone应用程序被放入一个叫做沙盒(sandbox)的具有安全性的构造中。程序只能访问自己沙盒中的资源。

iPhone 应用程序与 Mac OS 上的程序基本上相同、 只是程序目录下有一些不同。可以通过 AddressBook 等构造访问其他的功能或构造体。

iPhone 应用程序的目录构造如下所示:

/Applications/
 [Application1]/
  Application1.app
  Documents/
  Library/
  tmp/
 [Application2]/
  Application2.app
  Documents/
  Library/
  tmp/

工程项目的构成
工程项目的构成虽然根据程序不同而不同,但基本上都是基于MVC模型,所以按照 Model、Controller、View 来组织目录形式。

比如以下的目录构成:

Classes
Libraries (各种中间件,程序库等)
JSON
ImageStore
其他程序模块
Controllers (与 View Controller 相关的类)
UIApplicationDelegate
UIViewController
Views (定制的视图,程序界面)
UITableViewCell的子类
UIView的子类
项目文件构成
接下来我们再看看程序工程中还有什么:
HelloWorld
|-- Classes
| |-- HelloWorldAppDelegate.h
| |-- HelloWorldAppDelegate.m
| |-- HelloWorldViewController.h
| `-- HelloWorldViewController.m
|-- HelloWorld.xcodeproj
|-- HelloWorldViewController.xib
|-- HelloWorld_Prefix.pch
|-- Info.plist
|-- MainWindow.xib
|-- build
| `-- HelloWorld.build
`-- main.m

.pch
预编译头文件,win32里经常会碰到,这里也有,包含了常用的头文件。
.plist
包含了项目自身的特性,比如说项目名称,默认加载的nib file,版本等。
.xib
程序的资源文件。用于简化编码过程,提高开发效率。
main.m
iphone程序的入口,类似于C/C++中的main函数。
main函数如下所示:

int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}

main函数的参数 argc 以及 argv[] 与C语言中的意思一样,支持命令行的输入。

接下来创建一个NSAutoreleasePool对象,用来自动管理程序的内存。

1 NSAutoreleasePool * pool = NSAutoreleasePool alloc] init];

最主要的是下面的 UIApplicationMain 的调用,通过它完成系统启动的过程,并形成一个事件驱动。

1 int retVal = UIApplicationMain(argc, argv, nil, nil);



上一回我们看到了iPhone的入口函数main,这之后它有是怎样启动应用程序,初始化的呢,这些都是通过 UIApplicationMain 来实现的。

其启动的流程图大致如下图所示:


1 int retVal = UIApplicationMain(argc, argv, nil, nil);


通过上面的语句,创建UIApplication实例。同时,查看应用程序的 Info.plist 文件(该文件记录了一些应用程序的基础信息,比如程序名称,版本,图标等)。该文件还包含应用程序资源文件的名称(nib文件,名称用NSMainNibFile键指定)。如下所示:

<key>NSMainNibFile</key>
<string>MainWindow</string>


上面的意思是指,在应用程序启动的时候,需要从nib文件中加载名为 MainWindow 的资源。

其实,nib文件也是参照项目中Resources组中MainWindow.xib文件,我们双击该文件,启动Interface Builder后可以看到下面的图示:

Interface Builder 中有以下4个项目:

File’s Owner 对象,实际上就是 UIApplication 的实例。
First Responder 对象。每个程序都会有一个第一响应者,比如鼠标事件,键盘事件等,它就是对应的那个对象。比如多文档程序中,menu的响应事件一般都是连接到FirstResponder中去的,因为主界面一般都在别的nib里面,此时的FirstResponder就是你的那个主nib的FileOwner。
Delegate 对象。
Window。应用程序启动的时候所显示的窗口。
应用程序启动之后,像下面图一样,你可以定制自己的行为。

程序启动之后,会发送消息给 UIApplicationDelegate 的 applicationDidFinishLaunching 方法,在这里我们完成自己的初始化过程。如下面的代码。

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}

- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}


[window addSubview:viewController.view] 表示 XXXXXXViewController.xib 、[window makeKeyAndVisible] 是显示该窗口。

总结以上的内容,iPhone应用程序的引导过程如下所示:

1 main.m → MainWindow.xib → XXXXXXDelegate.m → XXXXXXViewController.m → XXXXXXViewController.xib


或者看下面的图来理解。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值