Write Objective-C Code:
1.About Objective-C.
2.Classes and Objects.
3.Methods and Messaging.
4.Declared Properties and Accessor Methods.
5.Blocks.
6.Protocols and Categories.
7.Defined Types and Coding Strategies.
如果你是新的iOS或Mac OS X的编程,你需要与主要的Objective-C编程语言,熟悉。 Objective-C语言是一个不困难的语言,一旦你花一些时间,有了它,你会欣赏其优雅。 Objective-C语言,使复杂的面向对象编程。它扩展了标准的ANSI C编程语言的语法定义的类和方法。这也促进了动态扩展的类和接口的任何类都可以采用。
如果你是熟悉与ANSI C,下面的信息应该帮助你学习Objective-C语言的基本语法。如果您有与其他面向对象语言编程,你会发现,许多传统的面向对象的概念,如封装,继承和多态性,都是目前在Objective-C。如果你不熟悉的ANSI C,我们强烈建议您至少读的C语言概述,然后再尝试阅读这篇文章。
完全解释的Objective-C编程语言Objective-C语言。
关于Objective-C语言
Objective-C语言指定的语法定义的类和方法,以及其他结构,促进动态扩展类和自适应接口。 C的超集 C编程语言的超集,Objective-C的支持C.相同的基本语法,你得到的所有熟悉的事物,如原始类型(int,float等),结构,函数,指针,和控制流构造阿西夫... ELSE和for语句。您还可以使用标准C库例程,如宣布instdlib.h stdio.h中。 Objective-C的ANSI C增加了以下功能:
• 定义新类的句法公约
• 类和实例方法的公约“
• 方法调用的语法(称为消息)
• 声明属性和合成存取方法的语法
• 静态和动态类型的约定
• 块封装代码段,可以在任何时间执行 • 如协议和类别的基本语言扩展
不要担心,如果这些方面Objective-C的现在是你不熟悉的。正如你进步,通过本文的其余部分,你会了解他们。如果你是一个程序的程序员,新的面向对象的概念,它可以帮助第一个想到的对象,本质上是一个与它相关联的结构与功能。这个想法是不是太离谱的现实,特别是在运行时执行。
Objective-C的优势 Objective-C中除了提供大多数其他面向对象语言的抽象和机制,是一个非常有活力的语言,而活力是其最大的优势。它是动态的,因为它允许一个应用程序的行为以确定它正在运行时(即,在运行时) ,而不是固定的应用程序,内置时。因此Objective-C语言的活力,释放程序编译时和链接的时间限制和转移符号分辨率运行时,当用户在控制大部分的责任。 Objective-C的弹簧的活力,有三个来源: • 动态类型,使你的代码在运行时的类的对象来确定。的id数据类型使得能够在运行时替代任何类型的对象。因此您可以让运行的因素决定要使用什么样的对象,在你的代码中。动态打字,从而使您的程序具有更大的灵活性比静态类型呢,虽然不太严格的数据完整性的折衷。
注:静态类型,指定其中的类类型(例如NSString的* VAR ) ,也有它的好处,其实是比动态类型较为常用。例如,对于静态类型编译器完全可以分析你的代码。它带来了更好的性能和可预测您的代码。在其他面向对象的语言,有时也被称为动态打字弱类型,静态类型被称为强类型。 • 动态绑定允许你的代码在运行时确定要调用的方法,而不是在编译时。正如动态打字推迟对象的类成员,直到运行时的分辨率,动态绑定缓建决定调用哪个方法(或电话) ,直到运行。方法调用绑定代码在编译过程中,与其他面向对象的语言,只有当实际交付的消息,他们必然。 动态类型和动态绑定,运行因素确定接收机选择哪个方法被调用。例如,可以定义一个绘图程序了各种各样的图形形状从一个共同的的形状祖先类继承的类,你可以调用一个平局对象上的方法,而无需事先知道该对象的类,以及它将如何绘制本身。 • 动态加载,可以让你的程序在运行时添加模块的代码和其他资源。应用程序可以动态加载,加载可执行代码和资源,他们需要的,而不是在启动时加载所有的程序组件。此功能提高了性能。可以包含可执行代码的程序运行时图像集成的新类。
类与对象 在大多数其他面向对象的语言,支持Objective-C中的类封装数据和操作数据定义的行动。对象是一个类和一个运行实例,包含它自己的类的方法,类和指针的实例变量在内存中的副本。您可以创建一个对象在一个两步的过程称为分配和初始化。 在Objective-C类的规范需要两个部分:接口和实现。接口部分包含了类声明和定义实例变量和方法与类相关。与C代码一样,你定义头文件和源文件,你的代码的实施细则,把公众的声明。 (你可以把其他声明,你的执行文件,如果他们是公共编程接口的一部分。 )这些文件具有下表中列出的文件扩展名。
延期
源类型
。H
头文件。头文件包含类,类型,函数和常数声明。
。M
源文件。这个扩展的源文件可以包含Objective-C和C代码。
。毫米
源文件。这个扩展可以包含源文件除了Objective-C和C代码的C + +代码。只有当你使用这个扩展实际上是指从您的Objective-C代码的C + +类或功能。
当你想在你的源代码包含头文件,使用#import指令,这是类似C的#include指令,但它确保相同的文件没有包括超过一次。 图1显示了声明一个名为MyClass的类,它继承从基类(或根) , NSObject的语法。 (根类是所有其他类直接或间接继承。 )类的声明@ interfacecompiler指令和结束@年底指令的开始。在类名(用冒号分开)是父类的名称。在Objective-C中,一个类只能有一个父。大括号( {和})划定的代码块中声明的类的实例变量(有时也被称为冬麦区,和其他一些语言中称为成员变量) 。实例变量的声明是可选的。实例变量块的属性(图中未示出)和由类声明的方法的列表。分号字符标志着每个实例变量和方法声明的末尾。 图1 A类声明 一个类实现的语法是相似的。它始于与实施@编译器指令(后面的类名)和两端@端指令。方法实现之间。实施应始终导入其接口为一体的第一行代码的文件。
导入“ MyClass.h ”
@实现MyClass的
- ( ID) initWithString :(的NSString * ) ANAME
{
/ /代码放在这里
}
+ ( MyClass的*) myClassWithString : (的NSString ) ANAME
{
/ /代码放在这里
}
@结束
如前所述, Objective-C的支持动态类型包含对象的变量,但它也支持静态类型。静态类型的变量包括变量的类型声明中的类名。动态类型的变量使用的类型ID的对象,而不是。你会发现在某些情况下,使用动态类型的变量。例如,一个集合对象,如数组(其中包含的对象可能是未知的确切类型)可能会使用动态类型的变量。这种变量提供了极大的灵活性,并允许更大的活力, Objective-C程序。 这个例子显示静态和动态类型的变量声明:
MyClass的* myObject1 / /静态类型
ID myObject2 ; / /动态类型
NSString的用户名/ /从你的第一个iOS应用程序(静态类型)
注意的第一个声明中的* 。 Objective-C中,对象引用必须始终指针。如果这个要求并不完整意义上的给你,不要担心,你不会是一个能够开始编程Objective-C的指针专家。你只需要在静态类型的对象声明的变量名前记得把* 。 ID类型意味着一个指针。 方法和消息 如果你是新的面向对象的编程,它可能会帮助想作为一个函数,它的作用范围是向特定对象的方法。通过发送消息或消息对象,调用该对象的方法。在Objective-C的方法有两种:实例方法和类方法。 • 实例方法是一种方法,其执行范围到一个特定的类的实例。换句话说,在你调用一个实例方法,你必须首先创建一个类的实例。实例方法是最常见的类型的方法。 • A类方法是一种方法,其执行方法的类的作用域。它不需要一个对象的一个实例是一个消息的接收器。
该声明的方法,包括方法类型标识符,返回类型,一个或多个签名关键字,参数类型和名称信息。 insertObject : atIndex :实例方法的声明。
对于实例方法,报关之前由减号( - )符号类方法,相应的指示灯是一个加号(+ ) 。 “类方法” ,下面介绍类方法的更多细节。 方法的实际名称( insertObject : atIndex :)是一个串联的所有签名的关键字,包括冒号字符, 。冒号字符申报存在的一个参数。另外,在上述的例子中,这个方法有两个参数。如果一个方法没有参数,你省略冒号后的第一个(也是唯一的)签名关键字。 当你要调用一个方法,你这样做,通过发送消息的对象,它实现的方法,或者,换句话说,消息对象。 (尽管这句话“发送消息”是常用的调用方法“的代名词, ” Objective-C的运行时执行实际的发送。 )消息是方法的名字以及参数信息的方法的需求(正常符合输入您发送的邮件的对象)。动态调度,从而有利于Objective-C类的多态行为(多态性是指不同类型的对象的能力,以应对同样的消息。 )有时调用的方法是实现由接收消息的对象的类的超类。 要派遣一个消息时,运行时需要一个消息表达式。一个消息表达包围括号( [ ])消息本身(连同任何所需的参数) ,只是里面最左边的支架,接收消息的对象。例如,发送insertObject : atIndex :消息myArray变量中,所持对象,你可以使用下面的语法:
[ myArray的insertObject : AnObject的atIndex : 0];
为了避免众多的局部变量声明来存储临时结果, Objective-C的让你嵌套消息表达式。用于从每个嵌套的表达式的返回值作为参数,或作为接收对象,另一个消息。例如,您可以替换任何信息检索值与前面的例子中使用的变量。叫做myAppObject方法访问数组对象和对象插入到数组另一个对象,如果你有,你可以写上例如看起来像下面这样:
[ myAppObject theArray ] insertObject : myAppObject objectToInsert ] atIndex : 0 ];
Objective-C语言调用存取方法还提供了点语法。存取方法获取和设置一个对象的状态,因此封装,这是一个重要的特征的所有对象的关键。对象封装,或隐藏,他们的状态,并提出了一个通用的接口访问该状态的所有实例。使用点语法,你可以重写前面的例子:
[ myAppObject.theArray insertObject : myAppObject.objectToInsert atIndex : 0];
您也可以使用点语法分配:
myAppObject.theArray = aNewArray ;
这个语法就是用不同的方式来写[ myAppObject setTheArray : aNewArray ] ; 您已经使用点语法已经分配给你的第一个iOS应用中的一个变量:
self.userName = self.textField.text ;
“属性声明和存取方法”,下面更详细描述的存取方法。 类方法 虽然前面的例子发送消息到一个类的实例,你也可以发送邮件到类本身。 (A类是由运行时创建的类类型的对象) ,当消息一个类,你指定的方法必须被定义为一个类的方法,而不是实例方法。类方法是一种功能类似于静态类的方法在C + +。 你经常使用工厂方法的类方法,创建新的实例的类或访问某些与类相关的信息共享。一个类的方法声明的语法是相同的,除非您使用加号( + )符号,而不是一个减号方法类型标识符实例方法。 下面的例子演示了如何使用一个类的方法作为工厂方法类。在这种情况下, arraymethod是一个类方法NSArray类和继承的NSMutableArray分配并初始化类的新实例,并返回到代码。
的NSMutableArray * myArray的=零; / /零,基本上是相同的为NULL
/ /创建一个新的阵列,将其分配给myArray的变量。
myArray的= [ NSMutableArray里阵列];
声明的属性和存取方法 在一般意义上是一个项目的状态封装对象的属性。它可以是一个属性,例如一个名称或颜色或一个或多个其他对象的关系。对象的类定义了一个界面,使用户它的对象来获取和设置封装属性的值。执行此功能的方法被称为访问方法。 有两种类型的存取方法,每个方法必须符合命名约定。作为属性的getter “存取方法,它返回的属性值,具有相同的名称。一个“二传手”的访问器方法,从而树立了新的属性值,具有形式setPropertyName方法:属性名的第一个字母是大写的正确命名的存取方法是几种技术的Objective-C框架的一个关键要素。 。 Objective-C中提供声明的属性访问器方法的申报和实施有时作为一个符号上的便利。在你的第一个iOS应用程序,您宣布UserName属性:
@属性(非原子,副本)的NSString *用户名;
申报物业消除需要执行一个类暴露在每个属性的getter和setter方法。相反,你指定你想要的行为使用财产申报,然后要求编译器根据该声明的合成,创建实际的getter和setter方法。申报物业的样板代码数量减少,你必须写,作为一个结果,使你的代码更清洁,更不容易出错。 包括在你的类接口的方法声明的属性声明。基本宣告使用@物业编译器指令,类型信息和属性的名称。您还可以配置自定义选项,它定义了如何存取方法的行为该物业,该物业是否是一个薄弱的参考,无论是只读。 @物业指令后的括号中是选项。 下面的代码行说明了几个属性声明:
@财产BOOL标志; / /默认是简单地赋值
@属性(副本)的NSString * nameObject ; / /复制对象在分配过程中。
@属性(只读)的UIView * rootView ; / /声明只有一个getter方法。
在你的类的实现,你可以使用@合成的编译器指令,要求编译器生成的访问方法,根据规范在声明中:
@合成国旗;
@合成nameObject ;
@合成rootView ;
@综合报表可以结合在一个单一的线,如果你想要:
@的的合成的标志, nameObject , rootView ;
你也可以在@合成指令指示编译器添加了相应的实例变量,类定义。添加一个实例变量,属性名后,指定一个等号和你想要的实例变量的名称:
@合成nameObject = _nameObject ;
块 块是对象封装一个单位工作,在较抽象的术语,代码段可以在任何时间执行。他们基本上是便携式和匿名函数,人们可以通过在方法和函数作为参数或方法和函数可以返回。块本身有一个类型参数列表,并可能有一个推断或声明的返回类型。您也可以指定一个变量块,然后调用它,就像你将一个函数。 脱字符号(^)符号作为一个语法标记块。除此之外,还有其它熟悉的语法约定为参数,返回值和身体的块(即,被执行的代码) 。在下图中已经清楚的语法,特别是当一个块分配给一个变量。
然后,您可以调用块的变量,如果它是一个函数:
结果= myBlock (4) / /结果是28
块股份在当地的词法范围内的数据。块的这种特性是非常有用的,因为如果你实现一个方法,该方法定义了一个块,该块具有访问权限的方法(包括堆栈变量)以及函数和全局变量,包括实例变量的局部变量和参数。这种访问是只读的,但如果一个变量声明为__块修改,它的值是可以改变的块内。即使封闭的方法或函数块后已经返回其局部范围被破坏,局部变量坚持只要有一个参考的块的块对象的一部分。 方法或函数的参数,块可以作为一个回调。的方法或函数被调用时,执行某些工作,并在适当的时候,回调代码通过调用块要求额外信息或索取从特定程序的行为。块使呼叫者提供的回调代码的调用点。包装“上下文”结构所需的数据,而是块捕获来自同一个词法范围的方法或函数作为东道主的数据。因为并不一定要实现在一个单独的方法或函数的代码块,您的实现代码可以更简单,更容易理解。 Objective-C框架块参数的方法有很多。例如,的UIKit框架声明下面的类方法,它有两个参数,采取块:
+ (无效) animateWithDuration :延迟持续时间( NSTimeInterval ) : ( NSTimeInterval )延迟选项:选项( UIViewAnimationOptions )动画(无效(无效) ) ( ^ )动画完成: (无效( ^ ) ( BOOL成品) )完成;
通过这种方法,可以以动画视图。首块参数用于指定动画,动画完成后,完成任务的第二块参数。在下面的例子中,第一个块简单的设置视图的结束alpha属性为零(使其透明) 。第二块完全消除了看法。
[ UIView的animateWithDuration : 0.2动画:^ {
view.alpha = 0.0 ;
}完成:^ ( BOOL成品) {
如果(成品== YES )
[查看removeFromSuperview方法] ;
} ] ;
协议和类别 协议声明的方法,可以实现任何一类,即使这些类执行“议定书”没有一个共同的超类。协议方法定义是独立于任何特定的类的行为。协议只是定义一个接口,其他类是负责实施。当你的类实现一个协议的方法,你的类表示,以符合该协议。 从实际角度来看,协议定义,建立对象之间的合同,而不需要任何特定的类的实例的方法的列表。这份合同使这些对象之间的通信。一个对象要告诉另一个对象有关的事件,它的遭遇,或许要问有关这些事件的建议。 UIApplication类实现的应用程序所需的行为。而不是强迫你接受简单的应用程序的当前状态通知subclassUIApplication ,的UIApplication类提供这些通知通过调用其分配的委托对象的具体方法。一个对象,它实现UIApplicationDelegate协议的方法,可以接收这些通知,并提供适当的回应。 您可以指定你的类符合,或采用在接口块,协议将在尖括号中的协议名称( < >)后从它继承的类的名称。您表示采用theUITextFieldDelegate协议在你的iOS应用:
@接口HelloWorldViewController :的UIViewController <UITextFieldDelegate> {
}
@结束
您不必申报协议实施方法。 的协议的声明看起来类似于一类接口,协议不有一个父类,他们不定义实例变量(虽然他们可以声明属性)例外。下面的例子显示了一个简单的协议,声明一个方法:
@协议MyProtocol
- (无效) myProtocolMethod的;
@结束
对于许多委托协议,采用的协议是实施该协议所定义的方法简单的事。有些协议需要明确支持协议,协议可以指定必要和可选的方法。 当你开始探索Objective-C框架的头文件,你很快就会遇到这一个类似的行:
@接口的NSDate ( NSDateCreation )
该行通过声明一个类的语法约定封闭在括号中的类的名称。 Acategory是Objective-C语言,使您可以扩展一个类的接口,而无需它的子类的一个特点。类别中的方法成为类类型(你的程序的范围内)的一部分,所继承的所有类的子类。您可以发送邮件到任何实例调用一个方法在类中定义的类(或其子类) 。 您可以使用类别为手段,将相关的方法声明的头文件内。你甚至可以把不同类别不同的头文件中的声明。可可触摸和Cocoa框架使用这些技术整个头文件清晰度。您也可以使用匿名类(括号之间的任何文字)的私人执行文件隐藏的实例变量。 定义的类型及编码策略 Objective-C中有一些条款,你不应该使用变量的名字,因为他们保留用于特殊用途。这些条款为前缀的标志(例如,@接口和@结束)的编译器指令。其他保留条款定义的类型和文字去与那些类型。 Objective-C中使用了一些在某些情况下,你不会找到在ANSI C的定义的类型和文字,这些类型和文字替换ANSI C的。下表描述了几个重要的,其中包括对每种类型的允许文字。
类型
说明文字
ID
动态对象类型。负文字动态和静态类型的对象为零。
类
动态类类型。其负面的文字是零。
SEL
一个选择的数据类型的typedef ,这个数据类型代表一个方法在运行时的签名。其负面的文字是NULL 。
BOOL
布尔类型。字面的值是YES和NO。
你经常使用这些定义的类型和文字错误检查和控制流代码。在你的程序的控制流语句,你可以适当的文字,以确定如何进行测试。例如:
NSDate的* dateOfHire = [雇员dateOfHire ] ;
( dateOfHire ! =无) {
/ /处理这种情况下,
}
套用此代码,如果该对象代表租用日期是不为零,换句话说,它是一个有效的对象,然后在某个方向的逻辑所得款项。这里有一个简便的方式做同样的分支:
NSDate的* dateOfHire = [雇员dateOfHire ] ;
如果( dateOfHire ) {
/ /处理这种情况下,
}
你甚至可以进一步降低这些代码行(假设你并不需要一个参考的dateOfHire对象) :
如果( [的雇员dateOfHire ] ) {
/ /处理这种情况下,
}
在大致相同的方式处理布尔值。在这个例子中的isEqual:方法返回一个布尔值:
BOOL等于= [对象A的isEqual :对象B ];
(等于== YES ) {
/ /处理这种情况下,
}
可以缩短这段代码的代码,你可以以同样的方式测试零的存在或不存在。 在Objective-C中,你可以发送邮件至零,无不良影响。事实上,有没有效果都没有,除了在运行时返回nil ,如果该方法应该返回一个对象。返回值为零保证,只要输入作为一个对象返回的消息发送。 另外两个重要的保留条款在Objective-C是自我和超。第一项,自我,是一个局部变量,您可以使用引用当前对象内消息实现,它是相当于在C + + 。可以替代的保留字超级自我,但只是作为一个消息表达式中的接收器。如果你发送一个消息到自我,在运行时首先查找当前对象的类的方法实现,如果它不能找到方法,它看起来它在它的父类(依此类推) 。如果您发送邮件超强,运行时会首先查找父类的方法实现。 自我和超的主要用途做发送消息。您发送一条消息时要调用的方法来实现自我之类的自我例如:
[自我doSomeWork ;
自我点符号也可用于调用访问器方法声明的属性,例如合成:
的NSString * theName = self.name ;
你经常发送邮件到超级覆盖从超类继承的方法(也就是重新实现) 。在这种情况下,所调用的方法覆盖的方法具有相同的签名。
学员评论
为之2013-12-11
mantis2013-05-30
你感兴趣的课程