1.第2章对C的扩展
本章将指导你构建第1个(当然还会有第二个)Objective-C程序,同时会讲解那些关键的新特性。
1.1.最简单的Objective-C程序
本节将讲解使用Xcode创建你的第一个Objective-C项目的全过程。本书有随书代码,请到;www.ituring.com.cn免费下载。
首先启动Xcode。启动完毕之后,你将会看到欢迎界面。
在欢迎界面中点击Createa new Xcode project选项。Xcode将在列表中显示它支持创建的各种项目类型。直接选中窗口左边MacOS X下的Application,在右边选择Command Line Tool图标,接下来点Next按钮。
在接下来的界面中,你需要对你的新项目进行设置。请在ProductName文本框中输入HelloObjective-C这个经典短语,然后在CompanyIdentifier文本框填写你的公司或网站地址的DNS反向格式,比如com .mywebsite。最后一个下拉列表框选择我们想要创建的命令行工具类型:Foundation。
接下来是存储位置。
单击Save按钮之后,Xcode会显示它的主窗口,即项目窗口。此窗口展示了项目的各组成部分以及编辑窗格。main.m就是包含了Hello Objective-C程序代码的源文件。
Xcode体贴地在main.m中为每个新项目都准备了样本代码。我们可以让HelloObjective-C应用程序比Xcode提供的样本代码更简单一些。删除HelloObjective-C中的所有内容,并替换为以下代码:
//
// main.m
// Hello mm
// 创建于六一儿童节的Hello world
// Created by mouyong on13-6-1.
// Copyright (c) 2013年 mouyong. Allrights reserved.
//
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
// insert codehere...
NSLog(@"Hello,World!");
return 0;
}//main
源代码只有转换成可以运行的程序之后才有意义。点击左上角的Run按钮或按下Command+R,就会生成并运行程序。只要没有任何语法错误,Xcode就会编译并链接你的程序,然后再运行它。
1.2.解构Hello Objective-C程序
Xcode通过.m扩展名来表示文件使用的是Objective-C代码,应由Objective-C编译器处理。而C编译器处理.c文件,C++编译器处理.cpp文件。在Xcode中,所有这些编译工作默认由LLVM处理,这个编译器能够理解C语言的全部3个变体。
如果你了解普通的C语言,那么你应该很熟悉main文件中包含的这两行代码:main()的声明语句和结尾的return 0语句。请记住Objective-C本质上就是C语言。
1.3.#import语句
与C语言一样,Objective-C使用头文件来包含结构体、符号常量和函数原型等元素的声明。#import是由Xcode使用的编译器提供的,Xcode在你编译Objective-C、C和C++程序时会使用它。#import可保证头文件只被包含一次,无论此命令在该文件中出现了多少次。
这里的#import <Fundation/Fundation.h>语句告诉编译器查找Foundation框架中Foundation.h头文件。
1.4.框架
框架是一种把头文件、库、图片、声音等内容聚集在一个独立单元中的集合体。苹果公司将Cocoa、Carbon、QuickTime和OpenGL等技术作为框架集来提供。Cocoa的组成部分有Foundation和Application Kit(简称AppKit)框架。此外还有一套支持型框架,包含了Core Animation和Core Image,它们为Cocoa增添了许多精彩的功能。
Fundation框架处理的是用户界面之下的那些层(Layer)的特性,比如数据结构和通信机制。本书中所有程序均以Foundation框架为基础。
说明:如果想要成为Cocoa的权威专家,还需要精通Cocoa的ApplicationKit框架,它包含了Cocoa的许多高级特性:用户界面元素、打印、颜色和声音管理、AppleScript支持等。想要了解更多的信息,请参阅JackNutting、David Mark和Jeff LaMarche共同编著的Learn Cocoa on the Mac
每个框架都是一个重要的技术集合,通常包含数十个甚至上百个头文件。每个框架都有一个主头文件,它包含了框架内所有头文件。只要导入这个头文件,就可以访问框架内的所有功能。
Foundation框架的头文件占用了近1MB的磁盘空间,包含了14000多行代码,涵盖了100多个文件。只要使用#import <Foundation/Foundation.h>来包含主头文件,就能获得整个集合。也许你担心读取每个文件的文本会消耗编译器很多时间,但是Xcode非常聪明:它使用预编译头文件来加快读取速度,通过#import导入这种文件时,加载速度会很快。
如果你很好奇Foundation框架包含了哪些头文件,你可以查看/System/Library/Frameworks/Foundation.framework/Headers/。只要不去移除或更改,仅仅浏览并不会破坏框架。
1.5.NSLog()和@“字符串”
Hello Objective-C中的第一行(也是唯一一行)代码使用了NSLog()函数:
NSLog(@“Hello Objective-C!”);
NSLog()与printf()很相似,向控制台输出Hello Objective-C!。NSLog()第一个参数也是一个可以包含格式说明符的字符串(比如%d)。你甚至可以直接在Objective-C中直接使用printf()函数。但我们还是建议使用NSLog(),因为它添加了一些特性,比如时间戳、日期戳和自动附加换行符(\n)等。
1.避免名称冲突的NS前缀
Cocoa给其所有函数、常量和类型名称都添加了NS前缀。这个前缀告诉我们函数来自Cocoa。
2.NSString:@是本体
在语句中我们看到字符串写成@”Hello,Objective-C!”。@符号是Objective-C在标准C语言基础上添加的特性之一。@符号意味着引号内的字符串应作为Cocoa的NSString元素来处理。
NSString元素集成了大量的特性,在需要用字符串时,通过Cocoa可以随时使用它们。下面列出了NSString所支持的部分功能:
❖告诉你它的长度有多少;
❖将自身与其他字符串进行比较;
❖将自身转换成整型值或浮点值。
在第8章中将更多地用到并研究NSString元素。
1.6.布尔类型
许多编程语言都支持布尔类型,它指的是可以存储真假值的变量类型。Objective-C也不例外。
Objective-C提供了一个BOOL,它具有YES和NO两个值,而不是真假。它比C语言的bool类型早诞生了十多年。这两种不同的布尔类型可以在同一个程序中共存,但是如果你在编写Cocoa代码,那你只能使用BOOL。
说明 Objective-C中的BOOL实际上是一种对带符号的字符类型的类型定义,它使用8位的存储空间。通过#define指令把YES定义为1,NO定义为0.Objective-C并不会将BOOL作为仅能保存YES和NO值的真正布尔类型来处理。编译器仍将BOOL认作8位二进制数,YES和NO只是在习惯上的一种理解。这样会引发一个小问题:如果不小心将一个大于1字节的整型值赋给一个BOOL变量,那么只有低位字节会用作BOOL值。如果该低位字节刚好为0(比方说8960),BOOL值将会被认作0,即NO值。
BOOL强大的实用功能
为了理解BOOL的实用功能,我们现在解释BOOL Party。此项目的作用是比较两个整数来判断它们是否相同。除了main()函数之外,此程序还定义了另外两个函数。第一个函数是areIntsDifferent(),它接受两个整型数,返回一个BOOL值:两个整数相同返回YES,不同则返回NO。第二个函数是boolString(),它接受一个BOOL参数并返回一个字符串,参数是YES时返回@”YES”,参数是NO时返回@”NO”。如果想以可读的形式输出BOOL值,那么,使用这个函数会很方便。 main()中使用这两个函数就可以比较整数并输出结果了。
//
// main.m
// boolparty
// 第二章布尔类型
// Created bymouyongon13-6-2.
// Copyright(c) 2013年 mouyong. All rights reserved.
//
#import<Foundation/Foundation.h>
/*
如果两个整数值相同,返回真
否则返回假
*/
BOOL areIntsDifferent(int thing1,int thing2)
{
if (thing1==thing2) {
return YES;
}else{
return NO;
}
}//areIntsDifferent
/*
如果收到一个NO值,返回一个字符串的NO
否则,返回一个字符串的YES
*/
NSString*boolString(BOOL yesNo)
{
if (yesNo) {
return @"YES";
}else{
return @"NO";
}
}//boolString
int main(int argc,constchar * argv[])
{
BOOL areTheyDifferent;
areTheyDifferent=areIntsDifferent(5, 5);
NSLog(@"%d和%d相同不?%@",5,5,boolString(areTheyDifferent));
areTheyDifferent=areIntsDifferent(23, 42);
NSLog(@"%d和%d相同不?%@",23,42,boolString(areTheyDifferent));
return 0;
}//main
------------------------------------------------------------------------------------------------------------------------
2013-06-02 09:53:08.107boolparty[2415:303] 5和5相同不?YES
2013-06-02 09:53:08.109 boolparty[2415:303]23和42相同不?NO
------------------------------------------------------------------------------------------------------------------------
1.第一个函数
/*
如果两个整数值相同,返回真
否则返回假
*/
BOOL areIntsDifferent(int thing1,int thing2)
{
if (thing1==thing2) {
return YES;
}else{
return NO;
}
}//areIntsDifferent
经验丰富的C语言程序员也许会将这个函数写成这个样子(默然说话:我想我会这么做):
BOOL areIntsDifferent_faulty(int thing1,int thing2)
{
return thing1-thing2
}//areIntsDifferent
因为在C语言中非零值就是true。但在Objective-C,YES就是1,不是别的值,同样NO就是0,而不是别的值。所以如果按以上算法获得的BOOL值,就会在后续的代码中引发问题。例如,程序员可能这样使用这个函数:
if(areIntsDifferent_faulty(23,5)==YES){
//...
}
如果这样,判断肯定出错,因为23-5=18,而18不等1,所以会被判定为假。这与C语言是完全不同的结果。
如果一定要用减法的形式求真假,那就记住不要与YES直接比较,可以使用下面的写法(默然说话:就是我在第二个函数中使用的那样)
if(areIntsDifferent_faulty(23,5)){
//...
}
另外就是直接与NO比较,这是安全的,因为假值就是只有一个0。
2.第二个函数
NSString*boolString(BOOL yesNo)
{
if (yesNo) {
return @"YES";
}else{
return @"NO";
}
}//boolString
注意到返回值那个星号没?它表示boolString()的返回值类型是一个指向NSString的指针。这意味着函数会返回一个Cocoa字符串。
3.main
如前所见,NSLog()本质上就是具有特色的printf()函数,它接受格式字符串,并将后续参数的值插入到这个格式说明符中。需要特别注意的是,NSLog()里使用了一个%@。它的含义是什么呢?它表示NSLog()接受适当的参数,将其作为NSString(默然说话:对!%s不能输出NSString字符串),并使用该字符串中的字符,将其发送到控制台中。
说明 使用NSLog()输出任意对象的值时,都会使用%@格式来表示。在使用这个说明符时,对象会通过一个名为description的方法提供自己的NSLog()格式。
在这个程序中,你学习了Objective-C的BOOL类型以及指示真和假的常量YES和NO。你可以像使用int和float等类型一样使用BOOL:将其用作变量、函数的参数和函数的返回值。
1.7.小结
在本章中,我们学习了一些最基础的知识,下一章我们将进入面向对象编程的奇妙世界。
第3章 面向对象编程的基础知识
面向对象编程(Object-Oriented Programming)的缩写OOP,这是一种编程技术,最初是为了编写模拟程序而开发的。OOP很快就俘获了其他种类软件(尤其是涉及图形用户界面的软件)开发者的心。很快OOP就成为了业内一个非常重要的流行词。它被誉为具有魔力的银色子弹,可以使编程工作变得简单而愉悦。
当然,这种说法是明显的广告用语。要精通OOP,仍然需要学习和练习。不过它确实能确化某些编程任务,甚至能让编程变得更加有趣。本书将频繁讨论OOP,主要是因为Cocoa基于OOP概念,并且Objective-C是一种面向对象的语言。
那么到底什么是OOP呢?OOP是一种编程架构,可构建由多个对象组成的软件。对象就好比存在于计算机中的小零件,它们通过互相传递信息来完成工作。本章我们将关注OOP的基本概念,研究可实现OOP的编程风格,并讲解一些OOP特性背后的原理,最后会全面介绍OOP的机制。
说明 OOP演变自20世纪60年代的Simula、70年代的Clascal以及其他相关语言。C++、Java、Python和Objective-C等现代编程语言都从这些早期语言中获得了灵感。
在研究OOP的过程中,你恐怕要做好迎接各种陌生技术术语的准备。OOP包含了很多听起来非常奇怪的术语,这会让人误以为它非常神秘并且难以理解,但事实并非如此。你甚至会怀疑计算机科学家们之所以创造了这些夸张的词汇只是为了向人们显摆他们有多聪明。
在讨论OOP之前,先来看看OOP的一个关键概念:间接(indirection,默然说话:感觉应该是封装,但是单词又是这样。。。。唉。。。。)。
本人接受个人捐助,如果你觉得文章对你有用,并愿意对默然说话进行捐助,数额随意,默然说话将不胜感激。