分类: 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里看到.