今天写了一天的iphone程序,被iphone sdk发短信的功能折磨了一天, 苹果允许的发短信支持貌似仅限于sms://这样的url,这样做每次程序都要被迫中断,实在不爽,查阅了大量文档发现只有使用private framework才能自由的发送短信,而这又是苹果不允许的,不知道苹果下一版的sdk能否适当开放下短信发送的限制。
郁闷之余还是有所收获,那就是感叹object c这门语言在动态性方面确实牛逼,要不是之前用过python、lua这样完全动态语言,真要被这种语言的动态性折服,难怪jobs放言object c是王道,并声称object c才是开发mac、iphone程序的首选, 先来说说最大的感叹之处, 那就是object c可以在不修改原始代码的情况下,往原类中添加新的成员方法,例如:
在string.h中有如下定义:
@interface string {
}
- (const char*) asUtf8;
@end
现在有需求,需要扩展string类的功能,加入asGbk方法,但string类不是我们自己写,我们一般的做法是继承一个mystring,或者写一个utility函数,完成这种转换,但在object c中,可以这样写
新建stringex.h,如下定义:
@interface string (stringex )
- (const char*) asGbk;
@end
使用时记得#import “stringex.h“ 就可以了。
这样语法我在object c的手册里没有找到具体如何称呼(也可能视而不见,请各位指点),我暂且称之为编译期插入成员方法。
上面的语法,还可以成为sugar,毕竟这是在编译期完成的(难为gcc了),不过下面的语法则是完全动态。
在object c里,所有成员方法的调用都是发送消息-即所有方法的调用都是动态的,而object c为此也引入了一个难看的语法,如:
string* str = [string alloc]; //这里含义是调用string的静态方法alloc,string::alloc()
注意,alloc在上面定义中并不存在,但这样写不会error,而是warning,说明编译期不依赖alloc函数必须存在。
const char* utf8 = [str asUtf8]; //这里是调用方法asUtf8, str->asUtf()
有了这样的语法支持,那么就可以实现很多传统c++无法实现的设计模式,比如代理/协议模式, 目标/动作模式,这些模式在iphone sdk中随处可见。
最后再引出object c泛型支持就最自然不过了,再object c中id类型可以被赋值任何数据,类似与d语言auto,或者干脆就是python等脚本语言变量,例如:
id str = [string alloc];
const char* utf8 = [str asUtf8];
最后说下多态, 在c++中, 多态是指运行时确定的成员方法, 但c++中的动态仅限于继承树上的类, 所有类指针存在is a关系, 而object c显然没有这样限制, 比如circle和rectangle都有display方法, 但明显rectangle和circle没有继承关系, 在c++中, 这样的类是不存在多态调用的, 但object c可以, 例如:
circle* c=[circle alloc];
rectangle* r=[rectangle alloc];
id shape = i==1?c:r;
[shape display];