Widnows 下构建 iPhone 开发环境
开源的 App Store 游戏和应用 【截图】

Objective-C 快速入门

皮贝贝 posted @ 2010年6月06日 06:46 in iphone with tags objective-c iphone , 17217 阅读

 

Objective-C 快速入门

已经有 C 语言编程基础

1 Hello World

Objective-C 就是一种 C 语言, 所以你可以用 C 语法来编程.

#include <stdio.h>
int main (int argc, char* argv[])
{
  printf ("Hello World\n");
  return 0;
}

这样是完全可以的。

2 Hello World 2

Objective-C 是 C 的一个扩展集, 只是在 C 语言上添加了一些微妙而意义重大的特性而已。例如 #import 某种意义上可以 认为是 #include + #pragma once 的组合, 更加方便管理:

#import <stdio.h>
int main (int argc, char* argv[])
{
  printf ("Hello World\n");
  return 0;
}

3 语法简略

3.1 #import

#import "file.h" = #include "file.h"(.h, .cpp) + #pragma once(.h)

这个特性就是一个语法糖, 当然在 C 语言中也可以用后者来制造奇淫怪巧。

3.2 数据类型

添加了 BOOL 变量, 具有 YES  NO. 事实上在 Obj-C 内部是这个样子定义的:

typedef BOOL signed char;
#define YES 1
#define NO 0

所以这种拼凑的布尔不像 C++ 的 bool 彻底干净。看下面

BOOL isLarger (int value1, int value2)
{
        return value1 - value2;
}

if (isLarger (12, 4))    
{
        // Obj_C 不会到此: 8 != YES
}

所以一个好的编程习惯是, 宁可与假作比较, 而且不要耍巧.

另外, Obj-C 有一个叫 id 的类型, 他指向一个对象, 可以理解为 C 语言的 void*, 可以指向任何对象。

3.3 @ 符号

当在文件中看到 "@" 符号时候, 就表示你看到的是 Obj-C , 一个扩展的 C 了。 这点来说, Obj-C 像极了动态网页编程语言, 像 PHP 之类不都是在 Html 中嵌入式编程吗, 可以把 Obj-C 想象成嵌入进 C/C++ 的嵌入语言。 这样的思维去思考 Obj-C 编程, 会助你领悟精通。当然, 这只是你入门的捷径。

事实上, 在标准 C 中 @开头的是无效的, 所以 Obj-C 利用和扩展了这一点, 所以 Obj-C 的大部分关键字都是 @开头的。

3.4 @""

@"" 是将字符串转变成 NSString, 一个 NextStep 库的字符串类型(想想 std::string). NSLog () 是 Cocoa 提供的输向控制台的函数(同 printf, 不过中文好像不支持吧)

3.5 面向对象

@interface-@end  @implementation-@end 实现面向对象。

  • @interface 提供接口界面(给编译器或使用者),
  • @implementation 是实现。

一般分别位于 .h, .cpp 中。

由于编译器要知晓构建对象的内存结构, 所以把对象的数据成员变量声明在 @interface-@end 对中, 以花括号囊括。

@interface Shape: NSObject

// 花括号囊括了 类Shape 的成员变量, 和 C 的 struct 一样。
{
        int x, y;
        int width, height;
}
// 其他方法接口
- (void) setX: (int) x;

@end

3.6 方法调度程序

Obj-C 中的方法调用为 消息 机制。 即通过向一个对象发送消息来通知其做什么。 对象的方法就是相应这个消息来执行的代码。

[shape draw];

意义是向 shape 对象发送 draw 消息。 在 shape 对象接收到消息后,会查询相应的类, 查找到正确的方法来执行。而下面:

shape->draw();

意指调用 shape 的 draw() 方法来运行。 可以看出不同了: Obj-C 中方法是被动调用的, 你只需向这个对象发送这个 方法对应的消息即可。

3.7 对象的方法

void setX (int x);

而 Obj-C 中变成了

- (void) setX: (int) x;

调用是

[myobject setX: 12];

可以用 C 的强制类型转换来理解, 方法 setX 是 void 类型, 冒号后面是参数, 参数 x 是 int 类型。

如果是多个参数就比较麻烦了, 还需要制定后续参数的形参名称:

- (void) setXY: (int) x    withY: (int) y;

调用的时候, 需要指定形参的名称:

[myobject setXY: 12 withY: 13]; // myobject.setXY (12, 13)

3.8 对象的构建

myclass* myobject = [myclass new];

大致执行两个步骤:

  1. 为 myobject 对象分配好内存空间。
  2. 自动调用对象 myobject 的 init 方法。

所以可以认为 init 是构造函数的一种变体实现。

3.9 方法调度 self?

类在 Obj-C 里也会存在一个对象: 类对象。使用 Obj-C 实现面向对象时候, 要将对象直接或间接的继承自 NSObject, 因为 NSObject 内部声明了一个 isa 变量, 该变量保存了一个指针, 指向这个对象所属的类的类对象。 例如

继承关系链: NSObject <- Shape <- Round

 Shape 的实例化对象中, isa 指向 Shape 的类对象。 在 Round 的实例对象中, isa 指向 Round 的实例对象。 同样的在 类对象中, Round 的类对象中 isa 指向 Shape 的类对象,Shape 的类对象中的 isa 指向 NSObject 类对象。

在对对象进行方法调用时, 会产生一个名为 self 的隐藏参数, 这个参数是指向接收消息的对象的指针, 鉴于 C 语言的对象内存布局, 基类的东西总是排在前面, 所以这个 self指向的对象区域内的第一个东西便是 isa*。在函数的实现里, 可以使用这个 *self 变量。

如 :

[roundobj draw]

这时候产生的 self 指向 roundobj 对象, 其 isa 指向的是 Round 类对象。 所以会在 Round 类对象中先查找 draw 方法, 有则调用; 否则, 继续在 Round 类对象的 isa 指向的 Shape类对象中查找, 这样依次向上链式查找, 直到找到并调用。这种机制恰恰实现了面向对象编程中的多态。

3.10 super 

这是 Obj-C 提供的关键字, 不是参数也非变量(与 self 不同)。 所以就不必追究到对象的内存布局上去了, super 是为了需要调用超类的东西而生的。

3.11 对象? 指针?

Java 中一切都是指针, 只是看不到 * 而已; Obj-C 内部是同样的方式行事, 一切都是指针, 但只是因为是 C 的扩展, 所以你看到的都是 * .

3.12 @class 前向声明

其实 C 已经有了此功能, 只是变化了表达的方式而已。

// car.h

// 预声明, 前向引用, 避免因导入文件造成的文件依赖
@class Engine;

@interface Car : NSObject
{
  Engine* engine;
}
@end

 

Date: 2010-06-06 22:38:22

HTML generated by org-mode 6.33x in emacs 23

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter