- 浏览: 96544 次
- 性别:
- 来自: 北京
最新评论
-
atgoingguoat:
meunitem.xmlR.layout.menuitem, ...
Android实现九宫格 -
龙哥IT:
怎么实现不了
Android中LocationManager的简单使用,获取当前位置 -
fuss228:
m_xmlType 是什么 哪里定义的 哪里赋值的?
iphone开发 NSXMLParser解析xml文件 -
he_eh:
学习了 很好很强大
Android实现九宫格 -
joyhub2140:
如何实现每格读取一张不同的图片呢?
Android实现九宫格
做了一段时间,发现objective-c基础很重要,为了接下来更好的学习,建议多看看基础,找了点资料,保存一下。
Objective-C语言学习
翻译:发芽的石头
2010-03-10
转帖请注明转之 苹果开发中文网(http://www.CocoaDev.cn)
以上说明是本文不可分割的一部分。
Objective-C是Mac软件开发领域最主要的开发语言。假如我们对面向对象的思维已经C语言都很熟悉的话,对于我们学习Objective-C将会非常有用。假如我们对C语言还不熟悉的话,那我们需要学习一下C语言。
(1)
方法调用(Calling Methods)
为了能够尽快上手,我们先来看一些简单的例子。Objective-C语法里面基本的方法调用是这样的:
[object method];
[object methodWithInput:input];
对象的方法可以返回值:
output = [object methodWithOutput];
output = [object methodWithInputAndOutput:input];
我们也可以在类里面调用如何创建对象的方法。下面的这个例子里面,我们调用了NSString类的string方法:
id myObject = [NSString string];
id的类型意味着myObject这个变量可以指向任意类型的变量。当我们编译这个应用程序的时候,并不知道他实现的真实的类和方法。
在这个例子里面,很明显这个对象的类型应该是NSString,所以我们可以改一下他的类型:
NSString* myString = [NSString string];
现在myString就是一个NSString类型的变量。这个时候假如我们试图使用一个NSString没有实现的方法时,编译器就会警告我们。
一定要注意在对象类型的右边有一个星号。所有的Objective-C对象变量都是指针类型的。id类型已经预先被定义成一个指针类型了。所以我们不需要再加星号。
嵌套消息调用(Nested Messages)
在许多编程语言里面嵌套消息,或者嵌套函数看起来就像这样:
function1 ( function2() );
function2的返回值被传递给function1当输入参数。在Objective-C里面,嵌套消息调用就像这样:
[NSString stringWithFormat:[prefs format]];
我们应该尽量避免在一行代码里面嵌套调用超过两个。因为这样的话,代码的可读性就不太好。
多参输入的方法(Multi-Input Methods)
多个输入参数的方法。在Objective-C里面,一个方法名可以被分割成几段。在头文件里面,就应该这样子来定义一个多输入参数的方法:
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
我们这样来调用它:
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];
参数不一定要给它命名。在运行期系统里面这个方法真实的名字叫writeToFile:atomically:。
(2)
Accessors(Getter & Setter)
在Objective-C里面所有的实例对象默认都是私有的。所有在大多数情况下我们需要用accessors去读取或者设置变量的值。有两个语法都支持这样的操作,这个时传统的老的语法:
[photo setCaption:@"Day at the Beach"];
output = [photo caption];
第二行的代码其实并非直接去读对象实例的变量。事实上它调用的是名叫caption的方法。在Objective-C里大多数情况下我们不需要给getters加get的前缀。
无论什么时候我们见到方括号,其实我们都是向一个对象或者一个类发送了一个消息。
Dot Syntax
在Objective-C 2.0里面,新增加了一个"."操作的语法。在Mac OS X 10.5里面就使用了Objective-C 2.0语法:
photo.caption = @"Day at the Beach";
output = photo.caption;
我们两种方式都可以使用。但是在一个工程里面最好保持风格一致,只使用某一种。"."操作只能够被使用在setters和getters里面,而不能用在一般意思的方法上。
(3)
创建对象
主要有两种方式来创建一个对象。第一种办法像这面这样:
NSString* myString = [NSString string];
这是一种非常习惯性的风格。在这种方式情况下,我们创建的是系统自动释放(autoreleased)类型的对象。关于自动释放类型autoreleased,我们以后会深入讨论一下。然而在许多情况下,我们需要手动的去创建对象:
NSString* myString = [[NSString alloc] init];
这是一个嵌套的方法调用。第一个调用的NSString自己的alloc方法。这是一个相对比较底层的调用,因为他创建了内容,以及实例化了一个对象。
第二块代码调用了新创建对象的init方法。这个init方法实现了比较常用的基本设置,比如创建实例对象的参数。对于一般开发人员而言,实现这个客户的类的具体的细节并不清楚。
在一些情况下,我们可以用不通的初始化方式去赋初值:
NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];
(4)
基本的内存管理
假如我们正在为Mac OS X开发一个应用程序,我们可以选择是否启用垃圾回收机制。这就意味着我们不需要去考虑内存管理,除了一个特别复杂的情形我们需要处理一下。
然而,我们有的时候我们的开发环境没有垃圾回收机制,比如iPhone开发的时候就没有垃圾回收机制。在这种情况下,我们就需要了解一些基本的内存管理方面的概念。
假如我们手动的通过alloc创建了一个对象,我们需要用完这个对象后release它。我们不需要手动的去release一个autoreleased类型的对象,假如真的这样去做的话,我们的应用程序将会crash。
这里有两个例子:
// string1 will be released automatically
NSString* string1 = [NSString string];
// must release this when done
NSString* string2 = [[NSString alloc] init];
[string2 release];
就这个教程而言,我们可以人为autoreleased对象会在当前函数方法调用完成后被释放。
当然了,还有很多关于内存管理的只是我们需要学习,但是这需要我们了解更多的基本概念以后才能去涉及。
(5)
设计一个类的Interface
就Objective-C语言而言,创建一个类非常简单。它非常典型的分成了两个部分。
类的接口通常保存在ClassName.h文件里,它定义了实例的参数,以及一些公开的方法。
类的实现在ClassName.m文件里。它包含了真正运行的代码和那些方法。它还经常定义一些私有的方法。这些私有的方法对于子类是不可见的。
这里有一个接口文件的大概。类名Photo,所以文件名叫Photo.h:
#import
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
@end
首先,我们把Cocoa.h import进来。Cocoa的应用程序的所有的基本的类大多都是这样做的。#import宏指令会自动的避免把同一个文件包含多次。
@interface符号表明这是Photo类的声明。冒号指定了父类。上面这个例子父类就是NSObject。
在大括弧里面,有两个变量:caption和photographer。两个都是NSString类型的。当然了,他们也可以是任何别的类型包括id类型的。
最后@end结束整个声明。
增加方法
让我们为成员变量加一些getters:
#import
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- caption;
- photographer;
@end
别忘记,Objective-C方法不需要加get前缀。一个单独小横杆表明它是一个实例的方法。假如是一个加号的话,那就说明它是一个类的方法。
编译器默认的方法的返回类型为id。还有所有的方法的参数的默认类型也都是id类型的。所以上面的代码从技术上讲是对的。但是很少这么用。我们还是给它加上返回类型吧:
#import
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer;
@end
下面我们再加上setters:
#import
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer;
- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;
@end
Setters不需要返回任何值,所以我们把它的类型指定为void.
(6)
类的实现
我们通过实现getters来创建一个类的实现:
#import "Photo.h"
@implementation Photo
- (NSString*) caption {
return caption;
}
- (NSString*) photographer {
return photographer;
}
@end
这部分的代码由@implementation再来加上类名开始,以@end结束。就跟类的接口定义一样,所有的方法跟接口定义里的一样。所有的对象都必要既要定义也要实现。
假如我们以前也写过代码的话,Objective-C里面的getters看上去跟别的差不多。所以我们下面就来介绍setters,它需要一点说明。
- (void) setCaption: (NSString*)input
{
[caption autorelease];
caption = [input retain];
}
- (void) setPhotographer: (NSString*)input
{
[photographer autorelease];
photographer = [input retain];
}
每个setter处理两个变量。第一个是当前存在对象的应用。第二个是新的输入对象。在支持垃圾回收的开发环境里,我们只要直接赋新值就可以了:
- (void) setCaption: (NSString*)input {
caption = input;
}
但是假如我们不可以用垃圾回收机制的话,我们就需要先retain旧的对象,然后retain新的对象。
有两种方法可以释放一个引用对象:release 和 autorelease。标准的release会直接删除引用。autorelease方法会在将来的某个时候去release它。在它声明周期结束前,它会毫无疑问的存在。在本例中,上面setPhotographer中的photographer对象,将会在函数结束的时候被释放。
在setter里面用autorelease是安全的,因为新对象跟老的对象有可能是同一个对象有可能指向的是同一个对象。对于一个我们即将retain的对象,我们不应该立即release它。
这个也许现在看起来会困惑,但是随着我们的学习,会越来越能理解它。现在我们不需要立刻完全理解它。
初始化
我们可以创建一个初始化方法去给类的实例的成员变量赋初值:
- (id) init
{
if ( self = [super init] )
{
[self setCaption:@"Default Caption"];
[self setPhotographer:@"Default Photographer"];
}
return self;
}
上面的代码感觉没啥好解释的,虽然第二行代码好像看上去没啥用。这个是一个单等于号,就是把[super init]的值赋给了self。
它基本上是在调用父类去实现它的初始化。这个if代码段是设置默认值之前验证初始化是否成功。
释放资源Dealloc
这个dealloc方法是在当一个对象希望被从内容里面删除的时候调用。这个我们释放在子类里面引用成员变量的最好的时机:
- (void) dealloc
{
[caption release];
[photographer release];
[super dealloc];
}
开始两行我们发送了release通知给了两个成员变量。我们不要在这里用autorelease。用标准的release更快一点。
最后一行的[super dealloc];非常重要。我们必须要发送消息去让父类清除它自己。假如不这么做的话,这个对象其实没有被清除干净,存在内存泄露。
dealloc在垃圾回收机制下不会被调用到。取而代之的是,我们需要实现finalize方法。
(7)
More on Memory Management
Objective-C的内存管理系统基于引用记数。所有我们需要关心的就是跟踪我们引用,以及在运行期内是否真的释放了内存。
用最简单的术语来解释,当我们alloc一个对象的时候,应该在某个时候retain了它。每次我们调用了alloc或者retain之后,我们都必须要调用release。
///// 。。。图。。。。
这就是引用记数理论。但是在实践的时候,只有两种情况我们需要创建一个对象:
1. 成为一个类的成员变量
2. 只临时的在一个函数里面被使用
在更多的时候,一个成员变量的setter应该仅仅autorelease旧的对象,然后retain新的对象。我们只需要在dealloc的时候调用release就可以了。
所以真正需要做的就是管理函数内部的local的引用。唯一的原则就是:假如我们alloc或者copy了一个对象,那么我们在函数结束的时候需要release或者autorelease它。假如我们是通过别的方式创建的,就不管。
这里是管理成员对象的例子:
- (void) setTotalAmount: (NSNumber*)input
{
[totalAmount autorelease];
totalAmount = [input retain];
}
- (void) dealloc
{
[totalAmount release];
[super dealloc];
}
这里是本地引用的例子。我们只需要release我们用alloc创建的对象:
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];
// only release value1, not value2
[value1 release];
这里是用本地引用对象去设一个成员变量的例子:
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
[self setTotal:value1];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];
[self setTotal:value2];
[value1 release];
注意到如何管理本地引用其实都是一样的。不管你是否把它设给了一个成员变量。我们无须考虑setters的内部实现。
如果我们很好的理解了这些的话,我们基本上理解了80%的Objective-C内存管理方面的内容了。
(8)
Logging
在Objective-C里,往console写日记非常简单。事实上NSLog()跟C语言的printf()两个函数几乎完全相同,除了NSLog是用额外的“%@”去获得对象。
NSLog ( @"The current date and time is: %@", [NSDate date] );
我们可以log一个对象到console里去。NSLog函数调用要输出对象的description方法,然后打印返回的NSString。我们可以在自己的类里重写description方法,这样我们就可以得到一个自定义的字符串。
(9)
属性Properties
前面我们写caption和author的accessors的时候,你可以已经注意到了代码非常简明,应该可以被抽象提取出来。
属性在Objective-C里是一个新的功能。他可以让我们自动的生成accessors,另外还有一些别的优点。我们可以把上面Photo的类转成用属性来实现:
上面那个类原先的实现是这样:
#import
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer;
- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;
@end
假如用属性来实现就是这样:
#import
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer;
@end
@property是Objective-C来声明属性的编译指令。括号里面的"retain"指明了setter需要retain输入的对象。这行其他的部分指定了属性的类型以及名字。
下面让我们来看看这个类的实现:
#import "Photo.h"
@implementation Photo
@synthesize caption;
@synthesize photographer;
- (void) dealloc
{
[caption release];
[photographer release];
[super dealloc];
}
@end
@synthesize指令自动的生成了我们的setters和getters。所以我们只需要实现类的dealloc方法。
Accessors只有当他们原先没有的时候,才会被生成。所以可以放心大胆的去用@synthesize来指定属性。而且可以随意实现你自己的getter和setter。编译器会自己去找哪个方法没有。
属性声明还有别的选项,但是限于篇幅层次,我们下次再介绍。
(10)
调用nil对象的方法(Calling Methods on Nil)
在Objective-C里,nil对象被设计来跟NULL空指针关联的。他们的区别就是nil是一个对象,而NULL只是一个值。而且我们对于nil调用方法,不会产生crash或者抛出异常。
这个技术被framework通过多种不同的方式使用。最主要的就是我们现在在调用方法之前根本无须去检查这个对象是否是nil。假如我们调了nil对象的一个有返回值的方法,那么我们会得到一个nil返回值。
我们可以通过nil对象让我们的dealloc函数实现看上去更帅一点:
- (void) dealloc
{
self.caption = nil;
self.photographer = nil;
[super dealloc];
}
之所以可以这么做是因为我们给把nil对象设给了一个成员变量,setter就会retain nil对象(当然了这个时候nil对象啥事情也不会做)然后release旧的对象。这个方式来释放对象其实更好,因为这样做的话,成员变量连指向随机数据的机会都没有,而通过别的方式,出现指向随机数据的情形机会不可避免。
注意到我们调用的self.VAR这样的语法,这表示我们正在用setter,而且不会引起任何内存问题。假如我们直接去设值的话,就会有内存溢出:
// incorrect. causes a memory leak.
// use self.caption to go through setter
caption = nil;
(11)
Categories
Categories是Objective-C里面最常用到的功能之一。 基本上category可以让我们给已经存在的类增加方法,而不需要增加一个子类。而且不需要知道它内部具体的实现。
如果我们想增加某个framework自带的类的方法,这非常有效。如果我们想在我们程序工程的NSString能够增加一个方法,我们就可以使用category。甚至都不需要自己实现一个NSString的子类。
比如,我们想在NSString里面增加一个方法来判断它是否是一个URL,那我们就可以这么做:
#import
@interface NSString (Utilities)
- (BOOL) isURL;
@end
这跟类的定义非常类似。区别就是category没有父类,而且在括号里面要有category的名字。名字可以随便取,但是习惯叫法会让人比较明白category里面有些什么功能的方法。
这里是具体的实现。但是要注意,这本身并不是一个判断URL很好的实现。我们主要是为了整体的了解category的概念。
#import "NSString-Utilities.h"
@implementation NSString (Utilities)
- (BOOL) isURL
{
if ( [self hasPrefix:@"http://"] )
return YES;
else
return NO;
}
@end
现在我们可以在任何的NSString类对象里都可以调用这个方法了。下面的代码在console里面打印的"string1 is a URL":
NSString* string1 = @"http://www.CocoaDev.cn/";
NSString* string2 = @"Pixar";
if ( [string1 isURL] )
NSLog (@"string1 is a URL");
if ( [string2 isURL] )
NSLog (@"string2 is a URL");
跟子类不一样,category不能增加成员变量。我们还可以用category来重写类原先的存在的方法,但是这需要非常非常小心。
记住,当我们通过category来修改一个类的时候,它对应用程序里的这个类所有对象都起作用。
原文:http://www.cocoadev.cn/Objective-C/Learn-Objective-C.asp
发表评论
-
Cocos2d加载图片的方式
2011-02-15 18:11 6212分享一个我用cocos2d加载图片的方式,其实很简单,我 ... -
sdk3.2升级到4.0,支持多线程cocos2d遇到问题的解决办法
2011-02-15 17:29 3655- (void) swapBuffers { // IM ... -
cocoa在线中文参考库
2010-10-18 18:09 2395http://www.apple.com.cn/develop ... -
NSArray的基本操作代码
2010-10-09 17:00 22885/*----------------------- ... -
Objective-c中@class和#import
2010-09-27 10:08 2023二者的区别在于: 1.import会包含这个类的所有信息 ... -
iPhone Locate 定位技术
2010-06-30 18:15 2662找到一个关于iphone定位 ... -
cocos2D 创建动画帧
2010-06-22 18:27 1666http://www.dualface.com/?p=406 ... -
iphone 开发笔记
2010-06-15 18:57 1522retain 和copy的区别 原 ... -
iphone开发常用代码
2010-05-30 10:21 2171更改cell选中的背景 Java代码 //创建一个UIV ... -
关于NSTimeInterval的使用
2010-05-18 18:03 17760NSTimeInterval time = [[NSDate ... -
iphone开发 NSXMLParser解析xml文件
2010-05-18 17:55 10881xml文件如下:Question.xml,放在Resource ... -
使用NSTimer实现倒计时
2010-03-31 11:39 1602转载:原文地址 http://blog.sina.com.cn ...
相关推荐
综上所述,本教程覆盖了Objective-C编程语言的基础知识点,不仅包括语法和结构,还包括与C语言的兼容性、内存管理机制、面向对象编程的核心概念、以及如何在不同操作系统平台上进行开发的介绍。通过这些内容的学习,...
《Objective-C基础教程》是一本面向初学者的编程书籍,主要涵盖了Objective-C语言的基本概念、语法和编程实践,尤其适合那些想要踏入iOS应用开发领域的学习者。Objective-C是Apple公司开发的面向对象的编程语言,它...
中文名: Objective-C基础教程 作者: Mark Dalrymple Scott Knaster译者: 高朝勤 杨越 刘霞图书 分类: 软件 资源格式: PDF 版本: 扫描版 出版社: 人民邮电出版社 书号: ISBN: 9787115208774 发行时间: 2009...
Objective-C是一种面向对象的编程语言,它是在标准C语言的基础上发展起来的,并且完全兼容C语言。由于其面向对象的特性,Objective-C被广泛应用于苹果公司的iOS和OS X操作系统上的应用程序开发。 #### 二、...
本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中的框架,以及继承、复合、源文件组织等众多重要的面向对象编程技术。...
Objective-C在C语言的基础上增加了Smalltalk风格的消息传递机制,允许开发人员编写更简洁、更易于维护的代码。作为苹果公司的主要编程语言,Objective-C被广泛用于开发iOS和Mac应用。该语言提供了丰富的特性,如动态...
《Objective-C基础教程(第2版)》结合理论知识与示例程序,全面而系统地介绍了Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性、Cocoa工具包的功能及框架,以及继承、复合、源文件组织等众多重要的...
C语言强大的低级操作能力为Objective-C提供了底层支持,而Objective-C则在此基础上增加了很多面向对象的特性,使得开发者可以更容易地进行应用程序的开发。 本书内容的组织结构被设计得非常有条理,从基础的语法...
它介绍了Objective-C语言的基础知识和最新特性,生动有趣。”——Bob Boonstra 2. “我是Scott Knaster的老读者了,25年来他撰写了很多畅销Mac编程书,这本一如既往地棒。”——John A. Vink 本书全面系统地...
Objective-C继承了C语言的基础语法结构,并在此基础上增加了面向对象的特性,包括类(Class)、对象(Object)、消息传递(Message Passing)等概念。具体特点如下: 1. **动态性**: Objective-C是一种动态类型的语言,这...
资源名称:Objective-C基础教程(第2版) 资源截图在: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
Objective-C是C语言的超集,它扩展了C语言,加入了面向对象的特性。面向对象编程(OOP)的核心概念包括类、对象、继承、封装和多态。Objective-C通过消息传递机制实现了这些概念,使得代码更加模块化和可维护。 2....
### Objective-C基础语法学习项目详解 #### 一、Objective-C简介 Objective-C是一种面向对象的编程语言,由Smalltalk和C语言发展而来。它在20世纪80年代初被设计出来,并在苹果公司开发iOS和macOS应用程序时得到了...
《Objective-C基础教程》全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等...
《Objective-C基础教程》全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等...
本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中的框架,以及继承、复合、源文件组织等众多重要的面向对象编程技术。...
本教程“Objective-C基础教程第二版英文版”旨在为初学者提供全面的Objective-C学习指导,并附带配套源代码,以便于实践和理解。 首先,让我们深入了解一下Objective-C的基础知识。Objective-C在语法上与C语言相似...
- **与C语言兼容:** Objective-C保留了C语言的所有特性,并在此基础上进行了扩展,因此可以轻松地在Objective-C代码中使用C语言编写的库或代码。 #### 二、Objective-C语言的基础语法 **1. 类与对象** 在...
Objective-C基础教程.pdf(Learn Objective-C on the Mac中文版) 中文扫描版 + 英文电子书 + 源码 该资源在Mac下用BetterZIP压缩,共三个分卷,其他分卷在我的资源中找。 更新: Windows下使用7zip对part1解压...
Objective-C基础教程高清中文版(第2版)PDF。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。...