ObjectiveC学习笔记

Leave a comment

ObjectiveC基本语法

消息
在objectiveC中,向一个对象发送一个消息的语法为

[ obj method:parameter];

类似的功能在C++中写作

obj->method(parameter);

在java中写作
obj.method(parameter);

在smalltalk中写作
obj method:parameter

显而易见objectiveC和smalltalk的语法基本是相同的。

当有两个或者两个以上的参数时,通常试用以的语法
[ obj method:parameter1 WithSecondParameter:parameter2];

定义一个类的代码放在一个.h文件中,下面是一个例子。
//macdevexample1.h
@interface ClassName:SuperClassName{
        //begin of instance variables
        @private
                int a;
        @protected
                float b;
        @public
                double c;
        //end of instance variables
}
//begin of method declaration
– instanceExampleMethod1;//instance method with no parameter
+ classExampleMethod1;//class method

– exampleMethod2:(int)parameter1; //instance method with 1 parameter
– (int)exampleMethod3:(int)parameter1 WithSecondParameter:(double)parameter2
;//instance method with 2 parameters

– (float)b;//method can have the same name of variable
– (void)setb:(float)_b;
//end of method declaration
@end
//end of macdevexample1.h

ObjectiveC类的定义以@interface开始,@end结束。@end后面不需要加分号,但是加了
也不会有什么大问题。数据部分包含在大括号中,缺省为protected。
ObjectiveC中的方法都为public。在声明方法时在方法命前加-表示是类的实例可以调
用的方法, +表示是类对象可以调用的方法(类似于C++、java里面的static方法)。
ObjectiveC定义类方法的语法同smalltalk类似,而不是像C++/Java一样同algo/C保持
一致。对于从C++、java转过来的开发人员来说可能有些不习惯。

ObjectiveC方法若没有声明返回值则返回id类型数据,id实际上是一个指向所有类的指
针,具体以后讨论。

实现一个类的代码会放在一个.m文件里
#import macdevexample1.h
@implementation ClassName
– instanceExampleMethod1{
//code goes here
}
+ classExampleMethod1{
//code goes here
}
..
@end
在objectiveC中可以试用#import或者#include来包含一个头文件。在使用#import时每
个头文件只会被包含一次,避免了类和变量重复定义的问题。

创建一个类的实例通常使用如下代码
ClassA *objA = [[ClassA alloc] init];
或者
ClassA *objA = [ClassA new];
或者
id objA = [[ClassA alloc] init];

alloc为类方法,负责分配内存(在heap上),然后返回一个id。init是实例方法,负责
初始化,然后返回一个id。同alloc类似的还有+ allocFromZone:(NXZone *)zone方法
,zone会在以后讨论。init也会有带参数的initWithXXX之类的方法。new方法把分配内
存和初始化在一个方法内完成。但土人俺觉得[[ClassA alloc] init]更清晰一点。

C++、java里面的this在objectiveC里面叫self(Smalltalk,Python, Objective
Pascal,Ruby也叫self, VB里面叫Me,Perl里面用$_[0] (俺Perl没学明白,不太敢确
认),PHP用$this表示实例用self表示类)。Java中的super在objectiveC中也叫super。

ObjectiveC中的BOOL类型的值为Yes和No而不是true和false。

Category是ObjectiveC提出的一个对类进行扩展的办法。C#3.0中extension methods的
概念和ObjectiveC的Category类似。

一下是一个例子,我们首先定义一个mitbbsExampleLocation类,文件名为
mitbbsExampleLocation.h。

#import <Cocoa/Cocoa.h>
@interface mitbbsExampleLocation : NSObject {
        int x,y;
}
-(void)moveToX:(int)x andY:(int)y;
@end

下面是implementation。
#import "mitbbsExampleLocation.h"
@implementation mitbbsExampleLocation
-(void)moveToX:(int)x andY:(int)y{
        self->x = x;
        self->y = y;
}
@end

下面定义一个扩展mitbbsExampleLocation类的category,定义的方法就是在类的名字
后面加一个小括号,然后把category的名字写在小括号里面,文件名不太重要,但是最
好为DisplayData.h。
#import "mitbbsExampleLocation.h"

@interface mitbbsExampleLocation (DisplayData)
        -(void) displayLocation;
        -(void) displayX;
        -(void) displayY;
@end

下面是implementation

#import "DisplayData.h"
@implementation  mitbbsExampleLocation (DisplayData)
        -(void) displayLocation{
                printf("x=%d\ty=%d\n", self->x, self->y);
        }
        -(void) displayX{
                NSAutoreleasePool * Pool = [[NSAutoreleasePool alloc] init];
                NSLog([[NSString stringWithFormat:@"%d\n", self->x]
autorelease]);
                [Pool release];
        }
        -(void) displayY{
                //…………….
        }
@end

Protocol是ObjectiveC中实现多重继承的机制。ObjectiveC中有两种protocol,一种是
非正式的,一种是正式的。非正式的protocol只是在文档中规定应该实现的方法。正式
的Protocol和java中的interface类似。在protocol中开发人员可以定义方法但是不能
定义实例变量。
@protocol mitbbsExampleClear
 -(void) Clear;
@end

@interface betterLocation: mitbbsExampleLocation <mitbbsExampleClear>
         -(void) Clear{
                self->x = 0;
                self->y = 0;
        }
@end

ObjectiveC中的消息机制是其面向对象的核心。在objectiveC中,向一个对象发送一条
消息的语法为

[receiver messageName:parameter];

这条命令会被编译器翻译为C代码

objc_msgSend(receiver, @selector(messageName), parameter);

在这里我们第一次遇到selector的概念。selector在objectiveC中的关键字为SEL。

在GNUStep中, SEL的定义为如下C代码。
typedef const struct objc_selector
{
  void *sel_id;
  const char *sel_types;
} *SEL;

由此可见,selector实际上是一个由一个方法名的字符串和一个unique id组成的结构
。所有同名的方法共有一个selector。当向某个对象发送消息时,objectiveC实际上告
诉对象需要调用某个selector对应的方法,该对象会从自己的Class所保存的selector-
method对应列表中查找是否可以相应该selector对应的方法,如果有就该干啥干啥,如
果不存在该selector对应的方法,则在superClass里面查询,如果还是没有则调用
message forward机制。message forward机制以后会讨论。

ObjectiveC会向实例方法传递两个隐含的参数,第一个为self第二个为该方法所对应的
消息的selector。C++仅传递一个隐含参数this。同C相比增加的参数数量会影响性能,
在IA32平台,参数通过栈传递,在PowerPC和x86-64平台参数通过寄存器传递。因此在
PowerPC和x86-64平台增加的参数对性能的影响相对较小。

ObjectiveC的消息机制同C++相比更加灵活,但是相对效率较低。ObjectiveC本质上是
动态的语言,而C++本质上是静态的语言,动态语言的本质导致ObjectiveC的效率必然
比C++低。因此在使用ObjectiveC进行开发时,对性能要求比较高的部分最好不用使用
消息机制(不要试用[receiver message]),而尽可能使用单纯的C语言。

在使用C代码时,可以试用@defs来获取ObjectiveC的Class的结构从而访问ObjectiveC
中的private和protected变量。以上面的mitbbsExampleLocation为例。

首先我们定义一个struct

typedef struct {
 @defs(mitbbsExampleLocation);
} *PLocation;

然后把一个指向mitbbsExampleLocation的指针cast成PLocation类型的变量。
PLocation p = (PLocation)[[mitbbsExampleLocation alloc]init];
p->x = 0;
p->y = 0;

获取一个ObjectiveC类的方法可以使用以下方法。
以mitbbsExampleLocation类的moveToX:andY:为例,首先定义一个指向该函数的指针

void (*moveToXAndY)(id, SEL, int, int);

然后获取方法的地址

moveToXAndY = (void (*)(id, SEL, int, int))[aLocation methodForSelector:@
selector(moveToX:andY:)];

然后moveToXAndY可以和调用普通方法一样调用但需要有连个隐含参数
moveToXAndY(anId, @selector(moveToX:andY:), 1, 2);

methodForSelector方法是在NSObject类中定义的。 其返回值为IMP。IMP的定义为

typedef id (*IMP)(id, SEL, …);

所以IMP就是一个指向返回值为id的ObjectiveC方法。如果返回值为其他类型我们需要
像上面一样自己定义一个方法的指针。

NSObject是目前所有ObjectiveC类的根类。NSObject中的NS表示NeXTSTEP。NSObject是
在NSObject.h文件里定义的。其核心内容如下
@interface NSObject <NSObject> {
    Class       isa;
}

+ (void)load;

+ (void)initialize;
– (id)init;

+ (id)new;
+ (id)allocWithZone:(NSZone *)zone;
+ (id)alloc;
– (void)dealloc;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
– (void)finalize;
#endif

– (id)copy;
– (id)mutableCopy;

+ (id)copyWithZone:(NSZone *)zone;
+ (id)mutableCopyWithZone:(NSZone *)zone;

+ (Class)superclass;
+ (Class)class;
+ (void)poseAsClass:(Class)aClass;
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;
+ (BOOL)conformsToProtocol:(Protocol *)protocol;
– (IMP)methodForSelector:(SEL)aSelector;
+ (IMP)instanceMethodForSelector:(SEL)aSelector;
+ (int)version;
+ (void)setVersion:(int)aVersion;
– (void)doesNotRecognizeSelector:(SEL)aSelector;
– (void)forwardInvocation:(NSInvocation *)anInvocation;
– (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;

+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector;

#if MAC_OS_X_VERSION_10_2 <= MAC_OS_X_VERSION_MAX_ALLOWED
+ (BOOL)isSubclassOfClass:(Class)aClass;
#endif

+ (NSString *)description;

– (Class)classForCoder;
– (id)replacementObjectForCoder:(NSCoder *)aCoder;
– (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;

@end

先把所有的方法放在一边看数据。整个NSObject里面只有一个数据 Class        isa
。Class类型是在objc.h里面通过typedef定义的,原文为

typedef struct objc_class *Class;

所以Class就是一个指向objc_class结构的指针。而objc_class是在 objc-class.h里面
定义的,内容为

struct objc_class {                    
        struct objc_class *isa;
        struct objc_class *super_class;
        const char *name;              
        long version;
        long info;
        long instance_size;
        struct objc_ivar_list *ivars;

        struct objc_method_list **methodLists;

        struct objc_cache *cache;
        struct objc_protocol_list *protocols;
};

这里面最值的注意的是

const char *name;

这一行。objectiveC和C++不同,每个类的名字会被编译器存在编译后的代码中,这样
可以在运行时确定类的名字,这是C++中没有的功能。

struct objc_ivar_list *ivars; 包含了instance variable的信息,例如名字,类型
,位置,这样可以在运行时获得变量的相关信息。objc_ivar_list的定义为

struct objc_ivar_list {
        int ivar_count;
#ifdef __alpha__
        int space;
#endif
        struct objc_ivar ivar_list[1];          /* variable length structure
 */
};

在objc_ivar_list的定义中,定义objc_ivar的代码为
struct objc_ivar {
        char *ivar_name;
        char *ivar_type;
        int ivar_offset;
#ifdef __alpha__
        int space;
#endif
};

struct objc_method_list **methodLists;这一行储存所有的方法的信息。当一个类或
者一个实例收到一个消息的时候会在这个表里面查找有没有相对应的方法。同变量类似
,ObjectiveC可以在运行时获取方法的名字等信息。

struct objc_method_list {
        struct objc_method_list *obsolete;

        int method_count;
#ifdef __alpha__
        int space;
#endif
        struct objc_method method_list[1];      /* variable length structure
 */
};

typedef struct objc_method *Method;

struct objc_method {
        SEL method_name;
        char *method_types;
        IMP method_imp;
};

通过上面的分析,我们可以说isa指针(以及Class变量)和C++的vtable类似但是增加
了很多其他信息,这些信息在二进制代码中也是可读的,使用class-dump(http://www.codethecode.com/projects/class-dump/)直接从objectiveC编译完成的二进制代码生成interface信息。

id也是在objc.h中定义的,代码为

typedef struct objc_object {
        Class isa;
} *id;

所以本质上,id就是一个指向NSObject的实例的指针,由于在objectiveC中所有的类都
是NSObject的子类,所以id可以用来指向任何类的实例。

在很久以前,ObjectiveC中的基类叫做Object,后来NeXTSTEP和Sun一起合作开发了一
个叫做OpenStep的项目,所有的类前面都加上了NS。土人俺不知道这个NS到底是代表(N
)eXT(S)TEP还是(N)eXTSTEP-(S)UN。OpenStep是后来的GNUStep和Cocoa的基础,因此现
在的Cocoa中的类都带着NS。

现在我们已经提到了id,Class,SEL,IMP,BOOL, #import,@interface,@
implementation,@protocol,@end,@private,@protected,@public,@selector(
method_name), @defs(class_name)。

Getting started

Leave a comment

因为学过C++,所以再学MAC下编程相对会容易些。但是作为初学者呢,最重要的还是先打好自己的基础,所以就先推荐一些比较好的网站和论坛,对以后的学习都是有极大的帮助哦。

首当其冲的必然是我们苹果公司的网站了,因为IDE就是从那里down下来的,所以那里的资料当属最新的,有必要隔三岔五过去溜溜,补充一点,因为都是英文资料,所以呢还是要把自己的英文基本功打好,其实单词都是大学4,6级水平,所以时间长了也就没有恐惧感了。

有必要对接下来遇到的几个专用词汇做些解释,其实在前边的文章里也有过介绍。
Objective-C:是C语言的一个超集,具有面向对象属性。因为语法与C语言差异较大,因此没有C++这么流行。Mac OS X就是由Objective-C开发而成。Objective-C是学习Mac OS X平台软件开发的第一步。
Cocoa:Cocoa是Mac OS X开发API的昵称。有点类似MFC之于Windows。在学会Objective-C的语法之后,就可以开始学习Cocoa,开发Mac OS X应用程序了。
Quartz:是Mac OS X的Aqua图形界面的2D图形加速引擎。
XCode:是Mac OS X下集成开发环境。类似Visual Studio至于Windows。XCode是免费的,包含在了Mac OS X的安装光盘之中,也可以通过网络下载。
AppleScript:AppleScript的设计目的就是让没有编程经验的用户来编写一些实用的自动处理脚本。AppleScript的语法十分接近自然语言,但是这并不意味着AppleScript很弱,事实上,AppleScript非常强大,可以让很多的系统维护工作变得非常的简单。用户还可以通过AppleScrpit自带的录制工具录制一系列操作的“宏”,系统会自动生成AppleScript脚本,以便于重复这一系列操作。AppleScript是Mac OS X Geeks必学之杀手锏。
Shell:熟悉UNIX/Linux的读者一定知道Shell是什么。Mac OS X基于UNIX,并通过了UNIX 03认证,掌握Shell编程可以让系统维护变得相当简单——特别是维护服务器系统。如果你对Mac OS X Server有兴趣,就一定要学学Shell编程了。

最开始的网站呢,叫做BecomeAnXcoder , A free book for starting with Cocoa using Objective-C.  这是一个在线学习网站,里边同时提供有多种语言的pdf格式文档下载。同时会介绍些比较流行的学习mac编程的网站。

接下来呢同样是一个比较基础的网站 http://www.cocoadevcentral.com/  里边有一个教学板块,全是基础知识介绍。建议大家先看看这部分。我个人是先看Objective-C的语法,然后再看Cocoa 介绍。不好意思,忘了一个很重要的东西,那就是Xcode,我们的IDE,因为学计算机最重要的就是实践了,所以呢,在学习语言的同时要不断的练习里边的Sample,所以呢会使用Xcode是必要前提,因为在写这篇文章的时候,Xcode(目前是3.1.1版本)还在更新,所以以往出版出来的资料和最新的工具都会有些差异,不过不影响学习,如果需要了解这部分信息呢,最好还是去苹果网站,里边的资料很全很详细,呵呵。

然后呢就可以学习在使用Objective-C来进行Cocoa Application 编程,这方面的资料权威的有Learning Cocoa With Objective-C, Sams.Programming.In.Objective-C, Building Cocoa Applications – A Step-By-Step Guide , Cocoa.Programming.for.Mac.OS.X.3rd.Edition. 同样,其中有些在我前边的文章里也有介绍,或者大家也可以去网上搜索一下,实在找不到的同学可以给我留言或者发邮件,呵呵。潜心研读后会豁然开朗(注: 我还没有读完,等我开朗的时候就告诉大家,到时候可以一起分享,呵呵)。那个时候再进行深入学习应该问题不大,同时英语资料的阅读水平也会突飞猛进。

好了,我想先写到这里吧。因为我也是新手,在以后的文章里慢慢纪录自己学习的体会和心得,如果有不同想法的朋友也欢迎大家提出宝贵意见和建议,大家交流分享,知识就应该拿出来分享嘛,呵呵~~如果再有其他比较好的资料我也会推荐给大家的,呵呵。一起努力了,为了我们心爱的Apple…

以此自勉~~

2 Comments

写这篇blog呢,主要是想给自己一些鼓励,为接下来纪录自己学习新事物的过程做准备,因为从我内心来讲,感觉自己真的太懒了,以至于有时候都会以自己智商低为借口来逃避一些必须做的事情,结果呢必然是快到deadline的时候把自己搞的异常狼狈,有时候真的在想如果谁能帮助我克服懒惰的毛病,那我绝对应该给他一大笔钱。唉,所以希望自己能尽快克服啊,因为已经不是小孩子了,有很多责任和压力,还有无数的期待和信赖,我不愿看到他们失望的眼神,更不希望让自己失望,因为如果被自己打败了,那我就是真的失败了,但是我还没有真正证明过自己。有时候还天真的在想,如果有伯乐能发现我就好了,但是自己只是常在嘴上说,没有付出过努力,怎么可能得到那样的机会和运气,是啊,因为我还没准备好,不,其实是我还没准备过。迷茫了20几年,该是时候清醒了。不管接下来做什么,最重要的是坚持,孩子,姑且再叫你一声孩子,该长大了。要学会自己成长,面对一切未知的挑战。我始终都很相信你,因为你曾经优秀过,你曾经让大家刮目相看过,你也曾经让父母骄傲过。但是那已永远的成为历史 ,前面的路还很长,要加油,要有吃苦的精神,相信我,现在吃苦带给你以后的必定是荣耀和尊贵,这才是你应得的。不要平凡得过一生,更不能碌碌无为。想想父亲为这个家所付出的,我做的有他百分之一吗?真的很惭愧,自己是不是得了重病,病得卧床不起……好了,自己得命运还是掌握在自己手中的,不要再让机会从身边溜走,好好珍惜现在的时间,因为离那个人生最重要的时刻已经不远了,不能让未来的他们失望,因为你从来都不是甘于庸俗之人。要活的精彩必定要吃很多苦,这可是必做的功课。 好了,还是那句老话: 知识改变命运…

Mac OS X开发系列电子书

Leave a comment

简介
随着苹果公司的复兴,越来越多的开发人员转向Mac OS X平台的开发。不过OSX平台使用的是很特别的Objective-C而非常规的C/C++,这使得很多开发人员对Mac OS X平台的开发有些望而却步,因此学习Objective-C以及Mac平台下的开发工具就显得相当重要了。因此,我挑选了一些相对比较新Mac OS X的开发系列书籍,分享给所有对Mac OS X平台软件开发感兴趣的朋友们。这些书籍大多为基于Mac OS X 10.4 Tiger平台的,但是依然很有参考价值。包括Objective-C,Cocoa,Quartz,XCode,AppleScript,Shell编程等相关书籍。

如果你对编程不感兴趣,但是像深入的了解Mac OS X的话,强烈推荐你阅读Mac OS X Internals,虽然该书中有很多很专业的知识,但是这本书绝对是了解Mac OS X的不二之选。配合下面介绍中给出的该书的配套网站阅读,效果更佳。

对上述一些名词的说明:
Objective-C:是C语言的一个超集,具有面向对象属性。因为语法与C语言差异较大,因此没有C++这么流行。Mac OS X就是由Objective-C开发而成。Objective-C是学习Mac OS X平台软件开发的第一步。
Cocoa:Cocoa是Mac OS X开发API的昵称。有点类似MFC之于Windows。在学会Objective-C的语法之后,就可以开始学习Cocoa,开发Mac OS X应用程序了。
Quartz:是Mac OS X的Aqua图形界面的2D图形加速引擎。
XCode:是Mac OS X下集成开发环境。类似Visual Studio至于Windows。XCode是免费的,包含在了Mac OS X的安装光盘之中,也可以通过网络下载。
AppleScript:AppleScript的设计目的就是让没有编程经验的用户来编写一些实用的自动处理脚本。AppleScript的语法十分接近自然语言,但是这并不意味着AppleScript很弱,事实上,AppleScript非常强大,可以让很多的系统维护工作变得非常的简单。用户还可以通过AppleScrpit自带的录制工具录制一系列操作的“宏”,系统会自动生成AppleScript脚本,以便于重复这一系列操作。AppleScript是Mac OS X Geeks必学之杀手锏。
Shell:熟悉UNIX/Linux的读者一定知道Shell是什么。Mac OS X基于UNIX,并通过了UNIX 03认证,掌握Shell编程可以让系统维护变得相当简单——特别是维护服务器系统。如果你对Mac OS X Server有兴趣,就一定要学学Shell编程了。

更新了Cocoa Programming For Mac OS X第三版。阅读这本书至少需要懂得Objective-C,所以比较适合有Mac OS X开发经验的读者使用。

书名:TextMate: Power Editing for the Mac
作者:James Edward Gray II
出版商:The Pragmatic Programmers
出版日期:2007年2月
格式:PDF


书名:Cocoa® Programming for Mac® OS X, Third Edition
作者:Aaron Hillegass
出版商:Addison Wesley Professional
出版日期:2008年5月
文件格式:CHM


书名:Creating Mac Widgets With Dashcode
作者:William H. Murray and Chris H. Pappas
出版商: Apress
以电子书形式出版


书名:Mac OS X Leopard Beyond Manual
作者:Scott Meyers & Mike Lee
出版社:Apress
出版时间:2007年12月
文件格式:PDF
简介:本书全面的介绍了最新的Mac OS X LeopardOperation System的各方各面,从使用到程序开发。是难得一见的介绍Apple最新Operation SystemMac OS X Leopard的新书。


书名:Beginning Mac OS®X Tiger™ Dashboard Widget Development
作者:Fred Terry
出版社:Wiley Publishing
出版时间:2006年
文件格式:PDF
简介:本书为Mac OS X的Dashboard小工具的开发指南。Mac OS X 10.5 Leopard加入了Dashcode以方便Dashboard小工具的开发。


书名:Beginning Xcode
作者:James Bucanek
出版社:Wrox Press
出版时间:2006
文件格式:CHM


书名:Cocoa Programming for Mac OS X 2th Edition
作者:Aaron Hillegass
出版社:Addison Wesley Professional
出版时间:4/30/2004
文件格式:ZIP(包内为PDF)


书名:Mac OS X Internals: A Systems Approach
作者:Amit Singh
出版社:Addison Wesley Professional
出版时间:June 19, 2006
文件格式:CHM
配套网站: http://www.osxbook.com/


书名:Quartz 2D Graphics for Mac OS X® Developers
作者:R. Scott Thompson
出版社:Addison Wesley Professional
出版时间:March 10, 2006
文件格式:CHM


书名:Programming in Objective-C
作者:Stephen G. Kochan
出版社:Sams Publishing
出版时间:October 30, 2003
文件格式:CHM


书名:Step into Xcode Mac OS X Development
作者:Fritz Anderson
出版社: Addison Wesley Professional
出版时间:January 30, 2006
文件格式:CHM


书名:Wicked Cool Shell Scripts: 101 Scripts for Linux, Mac OS X, and Unix Systems
作者:Dave Taylor
出版社:No Starch Press
出版时间:2004
文件格式:CHM


书名:Beginning AppleScript®
作者:Stephen G. Kochan
出版社:Wiley Publishing, Inc.
出版时间:2005
文件格式:PDF