现在的位置: 首页 > 综合 > 正文

(2)iPhone开发基础-Hello World

2014年10月26日 ⁄ 综合 ⁄ 共 6517字 ⁄ 字号 评论关闭

学习一门新的语言,好的方法非常重要,特别是入门阶段,好的开始是成功的一半嘛。Hello World作为一个精典的开篇例程,主要在于它的简单易学,易于掌握。麻雀虽小,但五脏俱全,开篇我将以一个简单的Hello World例子来展现iPhone开发最基础的各个方面,通过这些基础的学习,我们再一步一步的向高级应用展开,从而挖掘iPhone开发的精髓。

 (1) 头文件:HelloWorld.h

#import <UIKit/UIKit.h>

@interface HelloWorld : UIApplication {
    UIWindow *window;
}

@end

 iPhone主要以Objective-C 语言为主要开发语言,它继承了C语言的所有特性,可以说是C语言的一个超集,它与C一样,通过.h头文件声明函数,变量等, 同时它也有许多C++的特性,主要是面向对象方面的支持, 下面为大家分析这个头文件:

       1) #import

        通过#import引入其它头文件,这与C或C++的#include有一些类似,同时与Java的import也有些类似,C, C++或Java程序员需要注意一下。

        2) @interface ... @end

        声明类以
@interface 开始,@end结束, 紧接着@interface是类名HelloWorld

        3) HelloWorld : UIApplication - 类名:父类名

       继承以
类名:父类名 的方式表示如果大家有过C#或Java经验,肯定会问:为什么没有限定符?是的,没有,所有声明类都是公开的(public), 继承也是公开的(public), 类似于C++的class ClassName : public ParentClass,
当然, 此处的public在Objective-C中是没有的。C#和Java的程序员需要注意,此处类似C#的public class ClassName : ParentClass, 类似于Java的public class ClassName extends ParentClass.

        4) 单继承

       单继承ObjC (Objective-C的简称, 通用的简称,并不是我创造的,呵呵)与Java, C#有点类似,ObjC中也有接口的概念,在接下来的章节中会为您揭晓。

       5) 成员变量

       成员变量,在{}中声明变量,它与其它语言用作包含类函数及变量声明不同,此处声明的是成员变量,并且全部是私有的,类似于C++, C#, Java中的private。

好,到此,我们算是揭开了iPhone开发的一角,当然,头文件并不是这么简单,还有更多的特性我们在以后的章节中慢慢道来!

接下来我们看看它的实现:

 (2) 实现文件:HelloWorld.m

#import "HelloWorld.h"

#import <CoreFoundation/CoreFoundation.h>
#import <UIKit/UIKit.h>
#import <UIKit/UITextView.h>
#import <UIKit/UIFont.h>

@implementation HelloWorld

- (void)applicationDidFinishLaunching: (UIApplication *) application {
    window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
	
    CGRect windowRect = [ [ UIScreen mainScreen ] applicationFrame ];
    windowRect.origin.x = windowRect.origin.y = 0.0f;
	
	
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    window.backgroundColor = [UIColor whiteColor];
	
    CGRect txtFrame = CGRectMake(50,150,150,150);
    UITextView *txtView = [[UITextView alloc] initWithFrame:txtFrame];
    txtView.text = @"HelloWorld";
    UIFont *font = [UIFont boldSystemFontOfSize:18.0];
    txtView.font = font;
	
    [ window  addSubview: txtView ];	
    [txtView release];		
    [window makeKeyAndVisible];
}

@end

        1) #import

            头文件的导入, 这里不赘述,与头文件中的#import相同

        2) 实现体

            实现文件以 @implementation 开始,紧接着的是类名:HelloWorld,中间是实现体,最后以@end接尾.

            在实现体中有个函数体: applicationDidFinishLaunching, 实际上这个函数已不被推荐使用,在iOS 3.0之后就使用application:didFinishLaunchingWithOptions:了,新的函数完成声明如下:

            - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

            所以将函数体中的函数 - (void)applicationDidFinishLaunching: (UIApplication *) application换成上面的声明后,结果是一样的,当然你的iOS必须是3.0或之后的版本。

        看到这,我想你一定晕头了,如果你有其它语言的开发经验,估计会更晕,这就是为什么我不在HelloWorld.h中声明任何函数的原因,下面我们就以这个复杂的新函数来说明。

        3) 函数范围

         
首先,最前面的 '-' 表示此函数的范围,是类的成员函数,与之对应的有 '+', 表示静态函数,我们可以通过函数的调用来加以区别:

  • [类名 函数名称]

              这种方式的语法是调用'+'函数,即调用静态函数,静态函数的概念在其它高级语言中都有详细说明,这里就不介绍了,原理是一样的。

  • [类实例 函数名称]

             这种方式对应的是调用成员函数,即以'-'声明的函数。

        4) 函数类型声明 -(参数类型)

           
紧下来是 (BOOL), ObjC中将类型放在括号中,此处表示函数返回类型是BOOL型,即 YES 或 NO (YES, NO与其它高级语言的 true, false等同).

        5) 函数名

          紧接着出场的是函数名,不过注意,此处的函数名是 "application:" 而非 "application", 注意它的区别了吗?其实为什么这样写,我们还是以函数的调用方式来加以理解:

  • [类实例 : (类型)变量 参数名:(类型)变量]

           过头来我们再看一下application:函数的声明:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

          看到没?"application:", 如果此处我们是"application",那紧接着的第一个参数是不是很不好表示了,为了统一调用方式,只有第一个参数没有参数名,后面的参数都是以参数名:(类型)参数变量 的方式来声明参数的。你现在应该知道它为什么以参数名:(参数类型)参数变量的方式来声明参数了,记住:第一个参数没有参数名。

至于函数体中的代码,主要是操作UI的,我会在以后的章节中单独介绍基本控件的使用,以及自定义控件的开发的章节中介绍。

(3) Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>English</string>
	<key>CFBundleDisplayName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundleExecutable</key>
	<string>${EXECUTABLE_NAME}</string>
	<key>CFBundleIconFile</key>
	<string></string>
	<key>CFBundleIdentifier</key>
	<string>${PRODUCT_NAME:rfc1034identifier}</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>1.0</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
</dict>
</plist>

info.plist (Information Property List), 程序信息属性表,此表是创建程序时由XCode自动创建的,也是 苹果 对iOS开发的推荐属性表,下面列出推荐属性与常用属性:

推荐属性:

  • CFBundleDevelopmentRegion

  • CFBundleDisplayName

  • CFBundleExecutable

  • CFBundleIconFiles

  • CFBundleIdentifier

  • CFBundleInfoDictionaryVersion

  • CFBundlePackageType

  • CFBundleVersion

  • LSRequiresIPhoneOS

  • NSMainNibFile

常用属性:

  • UIStatusBarStyle

  • UIInterfaceOrientation

  • UIRequiredDeviceCapabilities

  • UIRequiresPersistentWiFi

属性表有下面五种类型的系统内嵌关键字:

  • Core Foundation  基础框架关键字.

  • Launch Services  启动服务关键字,主要有两项是针对iOS的,一项是“是否是iPhone程序“,另一个是”执行该程序的最iOS版本号“,其它主要是针对MAC OS的。

  • Cocoa Cocoa和Cocoa Touch关键字.

  • Mac OS X  苹果系统程序关键字.

  • UIKit  iOS 应用程序关键字.

具体细项在苹果网站有详细说明,请查阅Information Property List Key Reference

下面我将一些iPhone开发的基础概念以我的理解在此说明

[Cocoa], 是MAC OS X的开发环境,包括Foundation 和 AppKit, 这个概念相当于 .Net 或 Java平台的概念,它是针对普通PC操作系统的开发环境。

[Cocoa Touch], 即手持设备开发环境,包括Foundation 和 UIKit, 相当于.Net的精简平台 或 J2ME,主要针对手机,PDA,IPad等平台的开发环境。

[MAC OS X],我们都知道是苹果操作系统,它相当于Liux, Windows等操作系统。

[iOS], 手持设备操作系统,与Windows CE, ARM linux, Andrio等系统一样,操供手机操作系统支持。

[Objective-C],是Cocoa平台的实现语言,相当于C# 和 Java语言,前者实现了.Net框架,后者实现了Java平台, 而ObjC实现了Cocoa框架。

[Foundation], 框架,类似于.Net 的.Net Framework 以及 Java 的JDK。

[UIKit和AppKit], 前者是实现iOS下的界面元素开发,后者是实现MAC OS X下的应用程序界面。

在此我们可以回顾一下HelloWorld.h头文件中的HelloWorld类继承自UIApplication, 同时包含(#import)了UIKit, 它说明我们的程序是基于iOS平台的界面开发。

(4) 入口文件 main.m

 

#import <UIKit/UIKit.h>

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

现在我们开始回到程序开始的地方,所有开发语言开发出来的程序总会有个入口,连Windows下的动态库都有DllMain, 关于iOS开发下“库”的概念,我会单独以一章来介绍。此处的入口与C语言相同, argc是参数个数,argv是参数值组, argc决定了参数值组的大小。

 ObjC的Foundation库与COM和Corba一样,对创建的对象进行管理,与JVM以及.Net虚拟机的内存管理有一些类似,我们知道所有的ObjC对象都是继承自NSObject, 它就是用来对类实例引用进行计数的,当某一对像的引用计数为0时,会调用该对象的dealloc以释放该对象, 对象创建时,引用计数为1, 以后给对象发送retain消息时,计数加1,而对象接收到release消息时,引用计数减1。

入口函数的第一行创建了一个NSAutoreleasePool类型的pool对象,同时调用了init函数,此处的alloc和init函数都是NSObject类的成员函数,NSAutoreleasePool类继承自它。NSAutoreleasePool就是对象引用计数的自动处理器。

NSAutoreleasePool是一个栈,可以有多个NSAutoreleasePool对象,通过发送drain来销毁栈顶的pool对象,同时弹出,这样下一个pool就为当前pool。

注意,对象需要发送autorelease消息以加入到当前pool中进行管理, 当NSAutoreleasePool栈接收到drain消息时,它就对当前pool管理的所有对象发送release消息,你可能会想,如果pool所管理的对象的引用计数不为0,而当前pool已经销毁,该怎么办?很遗憾,你的程序有bug了,这一切表明,你得小心的管理你的对象,以免臭虫的产生。

接下来通过UIApplicationMain调用HelloWorld对象进行界面的显示,直到界面退出,才执行下面的程序代码。

[pool release] 对NSAutoreleasePool实例进行释放。

return retVal; 返回界面执行的结果。

 到此,一个基本的HelloWorld例子终于完成了,当然你一定还有许多疑问,我在以后的章节中逐步的加入一些概念以阐明ObjC更多的特性。

抱歉!评论已关闭.