学习 Objective-C:入门篇
The Objective-C language is a simple computer language designed to enable sophisticated object-oriented programming. Objective-C extends the standard ANSI C language by providing syntax for defining classes, methods, and properties, as well as other constructs that promote dynamic extension of classes. The class syntax and design are based mostly on Smalltalk, one of the first object-oriented programming languages.
Objective-C语言是一种简单的,被设计成面向对象的计算机语言。Objective-C扩展了标准的ANSI C语言的语法包括定义类,方法,属性,当然还有其他一些结构以促进对类进行动态拓展(比方说:category)。类的语法和设计都是基于第一个面向对象的编程语言Smalltalk。
If you have programmed with object-oriented languages before, the following information should help you learn the basic syntax of Objective-C. Many of the traditional object-oriented concepts, such as encapsulation, inheritance, and polymorphism, are all present in Objective-C. There are a few important differences, but those differences are called out in this article and more detailed information is available if you need it.
如果你以前有面向对象的那编程经验,那下面的信息将会帮助你学习Objective-C的语法。许多传统的面向对象的概念如封装,继承和多态都会出现在Objective-C中。这里有一些重要的差别,有一些重要的不同点会出现在本篇文章中,如果你需要的的话,还有一些更详细的资料
If you have never programmed using an object-oriented language before, you need to have at least a basic understanding of the associated concepts before proceeding. The use of objects and object-oriented constructs is fundamental to the design of iPhone applications, and understanding how they interact is critical to creating your applications. For an overview of object-oriented concepts, see Object-Oriented Programming with Objective-C. In addition, see Cocoa Fundamentals Guide for information about the object-oriented design patterns used in Cocoa.
如果你以前从来没有面向对象的编程经验的话,你至少需要了解一些基础的概念。在iphone的应用程序中对象和面向对象的结构是你设计程序的基础,去理解他们怎么相互作用才能创建你的应用程序。对面向对象概念的总览,看Object-Oriented Programming with Objective-C。另外你也可以看Cocoa Fundamentals Guide里有关Cocoa编程的面向对象设计模式的信息
For a more detailed introduction to the Objective-C language and syntax, see The Objective-C 2.0 Programming Language.
需要更多有关Objective-C语言和语法的介绍你可以看The Objective-C 2.0 Programming Language。
目录 [隐藏]
|
[编辑]
Objective-C: A Superset of C
Objective-C:一个C语言的超集
Objective-C is a superset of the ANSI version of the C programming language and supports the same basic syntax as C. As with C code, you define header files and source files to separate public declarations from the implementation details of your code. Objective-C files use the file extensions listed in Table 1.
Objective-C是ANSI版本C语言的一个超集,它支持相同的C语言基本语法。与C代码一样,你定义头文件和源文件并分开申明文件和实现文件。在表1中显示了Objective-C文件使用的文件後缀名
Table 1 File extensions for Objective-C code
表 1 Objective-C的文件後缀名
Extension |
Source type |
.h |
Header files. Header files contain class, type, function, and constant declarations. |
.m |
Source files. This is the typical extension used for source files and can contain both Objective-C and C code. |
.mm |
Source files. A source file with this extension can contain C++ code in addition to Objective-C and C code. This extension should be used only if you actually refer to C++ classes or features from your Objective-C code. |
後缀名 |
源文件类型 |
.h |
头文件。头文件包涵类的定义;类型,方法以及常量的声明。 |
.m |
源文件。这个典型的扩展名用来定义源文件,可以同时包含C和Objective-C的代码。 |
.mm |
源文件。这个源文件是一个拓展型的源文件,可以包含C + +, Objective - C和C代码(三种同时)。这个後缀只有在你使用了C++类的时候才能使用 |
When you want to include header files in your source code, you can use the standard #include compiler directive but Objective-C provides a better way. The #import directive is identical to #include, except that it makes sure that the same file is never included more than once. The Objective-C samples and documentation all prefer the use of #import, and your own code should too.
当你想要在你的源文件中包含头文件的时候你可以使用标准的 #include指令但是Objective-C提供了更好的方法。它使用#import等同于#include,并且可以保证你的程序只包含相同的头文件一次。Objective-C的例子和文档都倾向于使用#import,你的代码也应一样
[编辑]
Strings
字符串
As a superset of C, Objective-C supports the same conventions for specifying strings as C. In other words, single characters are enclosed by single quotes and strings of characters are surrounded by double quotes. However, most Objective-C frameworks do not use C-style strings very often. Instead, most frameworks pass strings around in NSString objects.
作为C语言的超集,Objective-C支持和C语言一样规则的字符串。换句话说,单个字符用单引号,多个字符用双引号。事实上,大多数Objective-C框架不是常常使用C语言风格的字符串。取而代之的是把字符串放入NSString对象中。
The NSString class provides an object wrapper for strings that has all of the advantages you would expect, including built-in memory management for storing arbitrary-length strings, support for Unicode, printf-style formatting utilities, and more. Because such strings are used commonly though, Objective-C provides a shorthand notation for creating NSString objects from constant values. To use this shorthand, all you have to do is precede a normal, double-quoted string with the @ symbol, as shown in the following examples:
NSString类提供了一个对象封装字符串, 其好处是您所期待的,包括内置的内存管理用于存储任意长度的字符串,支持Unicode(统一字符集),printf格式化输出,等等。因为这种字符串使用的是如此的多,所以Objective-C提供了简写符号从常量创建NSString对象。运用这个符号和正常初始化的效果是一样的,一个@符号紧跟两个双引号, 就像下面显示的例子那样:
NSString* myString = @"My String\n";
NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"];
// Create an Objective-C string from a C string
NSString* fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding];
[编辑]
Classes
类
As in most other object-oriented languages, classes in Objective-C provide the basic construct for encapsulating some data with the actions that operate on that data. An object is simply a runtime instance of a class, and contains its own in-memory copy of the instance variables declared by that class and pointers to the methods of the class.
对于大多数的面向对象的语言来说,类在Objective-C中提供了最基本的封装结构包含了数据,操作这些数据的方法。一个对象只是一个类运行时候的实例,包含了他自己的实例变量和指向类的方法。
The specification of a class in Objective-C requires two distinct pieces: the interface and the implementation. The interface portion contains the class declaration and defines the instance variables and methods associated with the class. The implementation portion contains the actual code for the methods of the class. Figure 1 shows the syntax for declaring a class called MyClass, which inherits from the NSObject base class. The class declaration always begins with the @interface compiler directive and ends with the @end directive. Following the class name (and separated from it by a colon) is the name of the parent class. The instance (or member) variables of the class are declared in a code block that is delineated by braces ({ and }). Following the instance variable block is the list of methods declared by the class. A semicolon character marks the end of each instance variable and method declaration.
在Objective-C中一个定义一个类需要有两个部分:第一接口,第二实现。接口文件包含了类的声明,定义了实例变量和方法。实现文件包含了具体的函数的实现代码。图一显示了一个叫MyClass的类,他继承自NSObject基类。类的定义总是从@interface开始到@end结束。在类名後面的(冒号後面的那个)是他父类的名称。实例(有的地方说成员)变量被定义在两个花括号之间({})。在实例变量下面块是方法的定义。一个分号用来结束一个变量或者方法。
Figure 1 A class declaration
图 1 一个类的定义
Listing 1 shows the implementation of MyClass from the preceding example. Like the class declaration, the class implementation is identified by two compiler directives—here, @implementation and @end. These directives provide the scoping information the compiler needs to associate the enclosed methods with the corresponding class. A method’s definition therefore matches its corresponding declaration in the interface, except for the inclusion of a code block.
表 1 显示了MyClass这个类的实现代码。就像类的定义规则一样,类实现文件也被两个标识框起来,一个是@implementtation,还有一个是@end。这两个指令标识符告诉编译器程序从那里开始编译到那里结束。类中的方法名称的定义和他接口文件中的定义是一样的除了具实现文件中有具体的代码以外。
Listing 1 A class implementation
表 1 一个类的实现
@implementation MyClass
- (id)initWithString:(NSString *) aName
{
if (self = [super init]) {
count count = 0;
data = nil;
name = [aName copy];
return self;
}
}
+ (MyClass *)createMyClassWithString: (NSString *) aName
{
return [[[self alloc] initWithString:aName] autorelease];
}
@end
Note: Although the preceding class declaration declared only methods, classes can also declare properties. For more information on properties, see “Properties”.
记住:虽然先前的类定义只有方法,类也可以定义变量。更多信息你看以看变量这一个章节。
When storing objects in variables, you always use a pointer type. Objective-C supports both strong and weak typing for variables containing objects. Strongly typed pointers include the class name in the variable type declaration. Weakly typed pointers use the type id for the object instead. Weakly typed pointers are used frequently for things such as collection classes, where the exact type of the objects in a collection may be unknown. If you are used to using strongly typed languages, you might think that the use of weakly typed variables would cause problems, but they actually provide tremendous flexibility and allow for much greater dynamism in Objective-C programs.
当你要把一个对象保存进变量,你总是使用指针类型。Objective-C同时支持强和弱变量对象。强类型对象在变量类型定义的时候包含了类名。弱对象使用id类型作为实例变量。如果你使用强类型的语法,你也许要注意如果使用了弱对象会有一些问题,但是事实上他们使Objective-C程序跟灵活更弹性。
The following example shows both strongly and weakly typed variable declarations for the MyClass class:
下面的例子同时显示了定义在MYClass中的强和弱两种类型的变量
MyClass* myObject1; // Strong typing
id myObject2; // Weak typing
[编辑]
Methods
函数
A class in Objective-C can declare two types of methods: instance methods and class methods. An instance method is a method whose execution is scoped to a particular instance of the class. In other words, before you call an instance method, you must first create an instance of the class. Class methods, by comparison, do not require you to create an instance, but more on that later.
在Objective-C中一个类可以定义两种类型的方法(函数):实例方法,类方法。一个实例方法只能在某个具体的实例对象中使用。换句话说就是当你要使用实例方法的时候你必须实例化类。类方法,不需要你创建实例对象就可以使用了。
The declaration of a method consists of the method type identifier, a return type, one or more signature keywords, and the parameter type and name information. Figure 2 shows the declaration of the insertObject:atIndex: instance method. The declaration is preceded by a minus (-) sign, which indicates that this is an instance method. The method’s actual name (insertObject:atIndex:) is a concatenation of all of the signature keywords, including colon characters. The colon characters declare the presence of a parameter. If a method has no parameters, you omit the colon after the first (and only) signature keyword. In this example, the method takes two parameters.
一个方法定义包含了方法类型,返回类型,一个或者多个关键词,参数类型和参数名。图 2 显示了insertObject:atIndex的实例方法。这个方法用减号(-)说明了他是一个实例方法。方法的实际名称是(insertObject:atIndex:)他是一串包含了冒号的字符串。冒号分割了参数。如果一个方法没有参数,你将在第一个关键词後面省略冒号。在这个例子中,这个方法有两个参数。
Figure 2 Method declaration syntax
图 2 方法定义语法
When you want to call a method, you do so by "messaging” the corresponding object. The message in this case is the method signature, along with the parameter information the method needs. All messages you send to an object are dispatched dynamically, thus facilitating the polymorphism behavior of Objective-C classes. In other words, if a subclass defines a method with the same signature as one of its parent classes, the subclass receives the message first and can opt to forward the message (or not) to its parent.
当你想要调用一个方法,你使用消息的方式呼叫那个对象。消息在这里表示方法名和参数。所有的消息的分派都是动态的,因此Objective-C的多态性。换句话说,如果子类定义了和他父类相同的方法,那子类将会先收到方法,然後再向上传递。
Messages are enclosed by brackets ([ and ]). Inside the brackets, the object receiving the message is on the left side and the message (along with any parameters required by the message) is on the right. For example, to send the insertObject:atIndex: message to an object in the myArray variable, you would use the following syntax:
消息的调用方式被放在了方括号之间([])。在这之间接受的对象放在左边,消息(伴随着参数)在右边。举个例子,给myArray对象发送insertObject:atIndex:这个消息你将会看到下面的语法:
[myArray insertObject:anObj atIndex:0];
To avoid declaring numerous local variables to store temporary results, Objective-C lets you nest messages. The return value from each nested message is used as a parameter, or as the target, of another message. For example, you could replace any of the variables used in the previous example with messages to retrieve the values. Thus, if you had another object called myAppObject that had methods for accessing the array object and the object to insert into the array, you could write the preceding example to look something like the following:
为了避免许多本地的变量保存进零时结果,Objective-C可以让你嵌套消息。返回值也许被嵌套进了其他消息作为参数或者目标对象,或者其他消息。举个例子,你可以用消息的方式取代所有的变量。这样如果你有其他对象调用myAppObject去访问数组对象然後这个对象插入数组中你可以写出像下面的例子那样:
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
Although the preceding examples sent messages to an instance of a class, you can also send messages to the class itself. When messaging a class, the method you specify must be defined as a class method instead of an instance method. You can think of class methods as something akin to (but not exactly like) static members in a C++ class.
虽然前面的例把消息发送给了类的实例,你也可以把消息发送给类本身。当消息是一个类,那你就要用类方法来替代实例方法。你可以把他想象成(当然不完全一样)静态的C++类
You typically use class methods as factory methods for creating new instances of the class or for accessing some piece of shared information associated with the class. The syntax for a class method declaration is identical to that of an instance method, with one exception. Instead of using a minus sign for the method type identifier, you use a plus (+) sign.
你使用类方法就像工厂方法那样去创建一个类的新实例或者访问类中的一些共享的信息。类方法的定义和实例方法的定义只有一个不一样那就是用加号(+)号代替减号(-)
The following example demonstrates the use of a class method as a factory method for a class. In this case, the arrayWithCapacity: method is a class method on the NSMutableArray class that allocates and initializes a new instance of the class and returns it to your code.
下面的例子演示了像工厂方法那样使用一个类方法。在这个例子中,arrayWithCapacity:方法是一个NSMutableArray 类方法 初始化然後生成一个新的实例对象返回给myArray
NSMutableArray* myArray = nil; // nil is essentially the same as NULL
// Create a new array and assign it to the myArray variable.
myArray = [NSMutableArray arrayWithCapacity:0];
[编辑]
Properties
属性
Properties are a convenience notation used to replace accessor method declarations. Properties do not create new instance variables in your class declaration. They are simply a shorthand for defining methods that access existing instance variables. Classes that expose instance variables can do so using the property notation instead of using getter and setter syntax. Classes can also use properties to expose “virtual” instance variables—that is, pieces of data that are computed dynamically and not actually stored in instance variables.
属性提供了比方法更方便的访问方式。属性不需要创建一个新的实例变量,他只是简单的访问现有的实例变量。类通过property标识符来替代getter和setter方法来表示实例变量。他也可以用来暴露“虚拟“实例变量--一种动态的不保存在实例变量中的特殊数据。
Practically speaking, properties reduce the amount of redundant code you have to write. Because most accessor methods are implemented in similar ways, properties eliminate the need to provide a distinct getter and setter method for each instance variable exposed in the class. Instead, you specify the behavior you want using the property declaration and then synthesize actual getter and setter methods based on that declaration at compile time.
实际上,属性减少了冗馀的代码。因为大多数访问的方法都定义了很简单的方式,属性标识符排除了那些必须用getter和setter方法来构造的实例变量。你在接口文件中可以用property标识符然後在实现文件中用synthesize标识符来取代getter和setter方法。
You include property declarations with the method declarations in your class interface. The basic definition uses the @property compiler directive, followed by the type information and name of the property. You can also configure the property with custom options, which define how the accessor methods behave. The following example shows a few simple property declarations:
你在你的类接口文件中定义了property标识符。最基本的使用方法是一个@property标识符後面跟着这个变量的属性,然後是变量名。你也可以自定义如何访问这些属性方法。下面这个例子显示了几种简单的属性定义:
@property BOOL flag;
@property (copy) NSString* nameObject; // Copy the object during assignment.
@property (readonly) UIView* rootView; // Create only a getter method.
Another benefit of properties is that you can use dot syntax when accessing them in your code, as shown in the following example:
另一个好处是你可以使用.点语法来访问,如下所示:
myObject.flag = YES;
CGRect viewFrame = myObject.rootView.frame;
Although the object and property names in the preceding example are contrived, they demonstrate the flexibility of properties. The dot syntax actually masks the corresponding set of method calls. Each readable property is backed by a method with the same name as the property. Each writable property is backed by an additional method of the form setPropertyName:, where the first letter of the property name is capitalized. (These methods are the actual implementation of properties and are the reason you can include property declarations for attributes of your class that are not backed by instance variables.) To implement the preceding code using methods instead of properties, you would write the following code:
虽然前面的对象和属性名称是我们自己创建的,但是他们提供了弹性的访问属性的方式。点语法用于set方法的调用。每一个易读的属性都被一个有着相同名称的方法访问。每一个可写的属性被setPropertyName:返回,当他的首字母是大写的。(这些方法用来保证你的类不被实例变量返回并且是这些属性的实现方法。用消息访问的方式实现先前的代码如下所示:)
[myObject setFlag:YES];
CGRect viewFrame = [[myObject rootView] frame];
For information on how to declare properties in your own classes, read "Properties" in The Objective-C 2.0 Programming Language.
需要了解如何在你的类中定义属性你可以参考The Objective-C 2.0 Programming Language中的属性那章。
[编辑]
Protocols and Delegates
协议和代理
A protocol declares methods that can be implemented by any class. Protocols are not classes themselves. They simply define an interface that other objects are responsible for implementing. When you implement the methods of a protocol in one of your classes, your class is said to conform to that protocol.
协议表示了方法可以被任何类所实现。协议本身不是类。他们只是简单定义了一个其他对象可以实现的接口。当你的类实现了协议中的某个方法的时候也就是说你的类实现了那个协议。
In iPhone OS, protocols are used frequently to implement delegate objects. A delegate object is an object that acts on behalf of, or in coordination with, another object. The best way to look at the interplay between protocols, delegates, and other objects is to look at an example.
在iphone OS中协议经常用来实现代理对象。一个代理是一种用来协同或者代表其他对象的特殊对象。要理解协议,代理,和其他对象的关系请看下面的例子:
The UIApplication class implements the required behavior of an application. Instead of forcing you to subclass UIApplication to receive simple notifications about the current state of the application, the UIApplication class delivers those notifications by calling specific methods of its assigned delegate object. An object that implements the methods of the UIApplicationDelegate protocol can receive those notifications and provide an appropriate response.
UIApplication类实现了运行应用程序必须的行为。如果你要跟踪UIApplication子类所发出的简单的消息如果现在的状态等等你可以使用呼叫他的代理对象的方法。一个实现了UIApplicationDelegate协议的对象可以接受并返回给你你要的东西,而不用去访问UIApplication对象本身。
The declaration of a protocol looks similar to that of a class interface, with the exceptions that protocols do not have a parent class and they do not define instance variables. The following example shows a simple protocol declaration with one method:
协议的定义和类接口的定义很像,但是他们没有父类,也不会定义实例变量。下面的例子显示了一个简单的协议:
@protocol MyProtocol
- (void)myProtocolMethod;
@end
In the case of many delegate protocols, adopting a protocol is simply a matter of implementing the methods defined by that protocol. There are some protocols that require you to state explicitly that you support the protocol, and protocols can specify both required and optional methods. As you get further into your development, however, you should spend a little more time learning about protocols and how they are used by reading "Protocols" in The Objective-C 2.0 Programming Language.
对于许多代理协议,接收协议比直接现实协议中定义的方法简单。有些协议需要你首先要接受那个协议,然後他会实现必须的和那些拓展的方法。当你在开发的路上走的更远的时候,事实上你需要一些时间来学习有关协议和他们如何使用的。你可以参考The Objective-C 2.0 Programming Language中的协议哪一章。
[编辑]
For More Information
更多信息
The preceding information was intended primarily to familiarize you with the basics of the Objective-C language. The subjects covered here reflect the language features you are most likely to encounter as you read through the rest of the documentation. These are not the only features of the language though, and you are encouraged to read more about the language in The Objective-C 2.0 Programming Language.
那些先前的信息是为了让你熟悉Objective-C语言中一些基本的东西。他复盖了剩下的文档中那些有关这个语言的特性。这些不全是这个语言特点的全部更多信息你可以参考The Objective-C 2.0 Programming Language这一章。