Chinaunix首页 | 论坛 | 博客
  • 博客访问: 149602
  • 博文数量: 100
  • 博客积分: 3132
  • 博客等级: 中校
  • 技术积分: 1075
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-17 23:38
文章分类

全部博文(100)

文章存档

2012年(63)

2011年(14)

2010年(23)

分类: BSD

2010-12-09 01:37:27

将下面的代码存为hello.m
#import

@interface HelloWorld : NSObject
- (void) hello;
@end

@implementation HelloWorld
- (void) hello {
    NSLog(@”hello world!”);
}
@end

int main(void) {
    HelloWorld *hw = [[HelloWorld alloc] init];
    [hw hello];
    [hw release];
}

在Mac OS X 10.6.2上编译它
gcc -o hello hello.m -L /System/Library/Frameworks/Foundation.framework/Foundation

这是编译的 x86 Mac版本, 而我们需要一个ARM iPhone版本
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc \
-arch armv6 -lobjc \
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk \
-framework Foundation -framework CoreFoundation \
-o iphone_hello hello.m

我们再来尝试使用 将接口和实现写在不同的文件中,并用Makefile来实现编译

以下代码,保存为Talker.h
#import
@interface Talker : NSObject
- (void) say: (char *) phrase;
@end

以下代码保存为Talker.m
#import “Talker.h”

@implementation Talker
- (void) say: (char *) phrase {
    printf(“%s\n”, phrase);
}
@end

以下代码保存为hello.m
#import  “Talker.h”
int main(void) {
    Talker *talker = [[Talker alloc] init];
    [talker say: "Hello, World!"];
    [talker release];
}

如果编译Mac OS X Intel版本,可用
mkdir build
gcc -o build/hello Talker.m hello.m -framework Foundation

如果编译iPhone ARM版本, 虽然也可以用命令行编译
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc \
-arch armv6 -lobjc \
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk \
-framework Foundation \
Talker.m hello.m \
-o build/iphone_hello

但建立一个Makefile会比较酷,哈哈

DEV = /Developer/Platforms/iPhoneOS.platform/Developer
SDK = $(DEV)/SDKs/iPhoneOS3.1.3.sdk
ARCH = armv6

CC = $(DEV)/usr/bin/gcc
CFLAGS = -arch $(ARCH) \
-I”$(SDK)/usr/include” \
-I”$(DEV)/usr/lib/gcc/arm-apple-darwin9/4.2.1/include” \
-F”$(SDK)/System/Library/Frameworks”\

LD = $(CC)
LDFLAGS = -arch $(ARCH) -lobjc \
-framework Foundation \
-L”$(SDK)/usr/lib” \
-F”$(SDK)/System/library/Frameworks” \

all: HelloApp

HelloApp: hello.o Talker.o
$(LD) $(LDFLAGS) -v -o $@ $^

%.o: %.m
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

clean:
rm -f *.o HelloApp

注意: 虽然里面有typedef char *STR; 的定义

但编译ARM版本不能通过

原理解释:

Phone系统是
1个所有的进程都以root权限运行的FreeBSD系统
所有的应用都以Objective-C创建
类似于COCOA的UIKit框架
文件系统重新组织过的FreeBSD Unix

Objective-C 调用一个方法,就是 往一个对象发送一个”方法名”的消息.
[obj doSomething];
这种发消息的机制, 可以发送任何消息给对象,即使接收消息的对象不能响应该消息. 这不同于静态类型的语言C++或者Java,
一个对象要调用的方法,必须预先定义好.
Objetvice-C的 接口与实现,必须放到不同的代码块里.

一个对象接收到消息,有3种处理方法: 转寄, 忽略,或者处理
OBJC_MSGSEND 的角色
在不同的类和方法之间的连续的消息流. 这个消息流 被_ObjC_MsgSend()函数处理.
编译器将 [foo doit]; 的语句 转换称 下面这样的C风格的函数调用
objc_msgSend(foo, @selector(doit));

注意: selector只是方法的名字而已. Method Selector被用来在运行时表示方法的名字, 方法选择器就是一个C字符串, 被映射到_cstring或者_cfsting节里面
当类被装载时, 由编译器生成的选择器, 会自动被运行时映射.

上面的C函数实际上就是

objc_msgSend(foo, “doit”);

objc_msgSend在Objective-C 2.0规范中有描述.
objc_msgSend, objc_msgSend_stret, objc_msgSendSuper, objc_msgSendSuper_stret.

1.因为大多数(不是所有的)消息,都通过这个入口点, 可以在这里实现跟踪和记录
2.程序员通常不会直接调用objc_msgSend函数
3.方法名直接从源代码转换到编译后的代码中, 你可以直接从IDA里看到.

阅读(1750) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~