learn objetive-c
Objective-C
Objective-C is the primary language used to write Mac software. If you're comfortable with basic object-oriented concepts and the C language, Objective-C will make a lot of sense. If you don't know C, you should read the C Tutorial first.
objective-c 是用于开发mac软件的主要语言。如果你熟悉面向对象思想和c语言,那么objective-c将简单。如果你没学过c,那你应该先去看下c的教程。
Copyright © 2008 Scott Stevenson
1
Calling Methods
To get started as quickly as possible, let's look at some simple examples. The basic syntax for calling a method on an object is this:
为了能够更快的上手,让我们先来看一些简单的例子吧。下面的基本的对象调用函数方法:
[object method];
[object methodWithInput:input];
Methods can return a value:
将返回一个值:
output = [object methodWithOutput];
output = [object methodWithInputAndOutput:input];
You can call methods on classes too, which is how you create objects. In the example below, we call the string method on the NSString class, which returns a new NSString object:
你也可以使用类直接调用方法。实际如在NSString类中直接调用string方法,返回一个NSString的对象:
id myObject = [NSString string];
The id type means that the myObject variable can refer to any kind of object, so the actual class and the methods it implements aren't known when you compile the app.
id类型表示myobject变量能够是任意类型,所以事实上在编译的时候系统并不知道其是什么类型。
在这个例子中,我们可以知道该类型是NSString,所以我们可以改为:
In this example, it's obvious the object type will be an NSString, so we can change the type:
NSString* myString = [NSString string];
This is now an NSString variable, so the compiler will warn us if we try to use a method on this object which NSString doesn't support.
表明是NSSting类型后,如果我们调用了一个NSString没有的方法编译的时候将会直接收到警告。
请注意的是关于对象类型,所有的objective-c对象都是指针类型。Id已被预定义为了一个指针类型,所以并没有警告提示。
Notice that there's a asterisk to the right of the object type. All Objective-C object variables are pointers types. The id type is predefined as a pointer type, so there's no need to add the asterisk.
Nested Messages(内部消息)
In many languages, nested method or function calls look like this:
在许多语言中,内部方法或函数的调用通常像下面这样:
function1 ( function2() );
The result of function2 is passed as input to function1. In Objective-C, nested messages look like this:
方法2的结果将作为参数输入到方法1中。而在objective-c中,内部方法调用如下:
[NSString stringWithFormat:[prefs format]];
Avoid nested nesting more than two message calls on a single line, as it easily gets unreadable.
尽量避免在一行中循环嵌套调用超过2个方法,否则将很难阅读。
Multi-Input Methods
Some methods take multiple input values. In Objective-C, a method name can be split up into several segments. In the header, a multi-input method looks like this:
一些方法需要输入多个参数。在objective-c中,一个方法名被拆分成几部分。在header中,方法定义如下:
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
You call the method like this:
你可以这样调用:
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];
These are not just named arguments. The method name is actuallywriteToFile:atomically: in the runtime system.
并不仅仅通过方法名字区分,在系统运行时实际上存在的是writeToFile:atomically:
Accessors(访问器)
All instance variables are private in Objective-C by default, so you should use accessors to get and set values in most cases. There are two syntaxes. This is the traditional 1.x syntax:
在objective-c中所有的实例变量默认都是private的,所以你需要使用访问控制去get set变量。
[photo setCaption:@"Day at the Beach"];
output = [photo caption];
The code on the second line is not reading the instance variable directly. It's actually calling a method named caption. In most cases, you don't add the "get" prefix to getters in Objective-C.
在上面第二行代码中不是直接读取变量。实际上是调用了一个名字为caption的方法。通常情况下你使用getter的时候无需添加get在变量前。无论你如何理解方括号里面的内容,都是调用了一个对象或类的方法。
Whenever you see code inside square brackets, you are sending a message to an object or a class.
Dot Syntax
The dot syntax for getters and setters is new in Objective-C 2.0, which is part of Mac OS X 10.5:
作为mac os x10.5的一部分,新的objective-c2.0中有了点存取语法,如:
photo.caption = @"Day at the Beach";
output = photo.caption;
You can use either style, but choose only one for each project. The dot syntax should only be used setters and getters, not for general purpose methods.
你可以使用其中任何一种风格,但最好只选一种。
3
Creating Objects
There are two main ways to create an object. The first is the one you saw before:
有两种创建对象的方法。一种就是前面的你看到的:
NSString* myString = [NSString string];
This is the more convenient automatic style. In this case, you are creating an autoreleased object, which we'll look at in more detail later. In many cases, though, you need to create an object using the manual style:
这是一种很方便的风格。在这种方法下,对象能够自动释放,后面我们将会详细介绍。然而在更多的情况下,我们需要手动创建一个对象:
NSString* myString = [[NSString alloc] init];
This is a nested method call. The first is the alloc method called on NSString itself. This is a relatively low-level call which reserves memory and instantiates an object.
通过了一个内部方法的调用。首先是调用NSString本身的alloc方法,该方法时底层用于开辟内存和实例化对象用的。
The second piece is a call to init on the new object. The init implementation usually does basic setup, such as creating instance variables. The details of that are unknown to you as a client of the class.
第二是用新生成的object调用了init方法。Init常用于基本的初始化,比如创建一些常量。有些情况下,你可以使用不同的init进行初始化。
In some cases, you may use a different version of init which takes input:
NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];
4
Basic Memory Management(基本的内存管理)
If you're writing an application for Mac OS X, you have the option to enable garbage collection. In general, this means that you don't have to think about memory management until you get to more complex cases.
如果你在写mac os x应用,你就应该选择实现垃圾回收。通常情况下,如果你开发一个要求不高的应用时,无需自行考虑内存管理。然而,你并不会总在一个支持垃圾回收的应用开发环境下工作。有些情况下,你必须理解基本的内存管理。
However, you may not always be working with an environment that supports garbage collection. In that case, you need to know a few basic concepts.
If you create an object using the manual alloc style, you need to releasethe object later. You should not manually release an autoreleased object because your application will crash if you do.
如果你使用alloc创建了一个对象,你就需要在后面自行release掉它。你不能够手动release掉一个声明为autoreleased的对象,否则你的应用将会崩溃。
Here are two examples:
看下面两个例子:
// string1 will be released automatically
NSString* string1 = [NSString string];
// must release this when done
NSString* string2 = [[NSString alloc] init];
[string2 release];
For this tutorial, you can assume that an automatic object will go away at the end of the current function.
There's more to learn about memory management, but it will make more sense after we look at a few more concepts.
5
Designing a Class Interface
The Objective-C syntax for creating a class is very simple. It typically comes in two parts.
创建一个类是比较简单的。通常需要两步。一个是使用.h文件存放变量和公有方法。使用.m文件实现这些公有方法。也用来定义一些private内部方法。
The class interface is usually stored in the ClassName.hfile, and defines instance variables and public methods.
The implementation is in the ClassName.m file and contains the actual code for these methods. It also often defines private methods that aren't available to clients of the class.
下面是一个photo的接口.h
Here's what an interface file looks like. The class is called Photo, so the file is named Photo.h:
#import <Cocoa/Cocoa.h>
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
@end
First, we import Cocoa.h, to pull in all of the basic classes for a Cocoa app. The #import directive automatically guards against including a single file multiple times.
首先,我们导入了cocoa.h。该文件声明了一个photo类,继承自NSObject类型。定义了两个变量caption和photographer。最后,我们使用@end结束声明。
The @interface says that this is a declaration of the class Photo. The colon specifies the superclass, which is NSObject.
Inside the curly brackets, there are two instance variables: caption andphotographer. Both are NSStrings, but they could be any object type, including id.
Finally, the @end symbol ends the class declaration.
Add Methods
Let's add some getters for the instance variables:
让我们先为变量添加getter和setter方法:
#import <Cocoa/Cocoa.h>
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- caption;
- photographer;
@end
Remember, Objective-C methods typically leave out the "get" prefix. A single dash before a method name means it's a instance method. A plus before a method name means it's a class method.
By default, the compiler assumes a method returns an id object, and that all input values are id. The above code is technically correct, but it's unusual. Let's add specific types for the return values:
#import <Cocoa/Cocoa.h>
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer;
@end
Now let's add setters:
#import <Cocoa/Cocoa.h>
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer;
- (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input;
@end
Setters don't need to return a value, so we just specify them as void.
Class Implementation
Let's create an implementation, starting with the getters:
让我们来实现方法:
#import "Photo.h"
@implementation Photo
- (NSString*) caption {
return caption;
}
- (NSString*) photographer {
return photographer;
}
@end
This part of the code starts with @implementation and the class name, and has @end, just like the interface. All methods must appear between these two statements.
The getters should look very familiar if you've ever written code, so let's move on to the setters, which need a bit more explanation:
- (void) setCaption: (NSString*)input
{
[caption autorelease];
caption = [input retain];
}
- (void) setPhotographer: (NSString*)input
{
[photographer autorelease];
photographer = [input retain];
}
Each setter deals with two variables. The first is a reference to the existing object, and the second is the new input object. In a garbage collected environment, we could just set the new value directly:
- (void) setCaption: (NSString*)input {
caption = input;
}
But if you can't use garbage collection, you need to release the old object, and retain the new one.
There are actually two ways to free a reference to an object: release andautorelease. The standard release will remove the reference immediately. The autorelease method will release it sometime soon, but it will definitely stay around until the end of the current function (unless you add custom code to specifically change this).
The autorelease method is safer inside a setter because the variables for the new and old values could point to the same object. You wouldn't want to immediately release an object which you're about to retain.
This may seem confusing right now, but it will make more sense as you progress. You don't need to understand it all yet.
Init
We can create an init method to set inital values for our instance variables:
重写init方法:
- (id) init
{
if ( self = [super init] )
{
[self setCaption:@"Default Caption"];
[self setPhotographer:@"Default Photographer"];
}
return self;
}
This is fairly self-explanatory, though the second line may look a bit unusual. This is a single equals sign, which assigns the result of [super init] to self.
This essentially just asks the superclass to do its own initialization. The if statement is verifying that the initialization was successful before trying to set default values.
Dealloc
The dealloc method is called on an object when it is being removed from memory. This is usually the best time to release references to all of your child instance variables:
重写dealloc方法
- (void) dealloc
{
[caption release];
[photographer release];
[super dealloc];
}
On the first two lines, we just send release to each of the instance variables. We don't need to use autorelease here, and the standard release is a bit faster.
The last line is very important. We have to send the message
[super dealloc] to ask the superclass to do its cleanup. If we don't do this, the object will not be removed, which is a memory leak.
The dealloc method is not called on objects if garbage collection is enabled. Instead, you implement the finalize method.
More on Memory Management(更多的内存管理)
Objective-C's memory management system is called reference counting. All you have to do is keep track of your references, and the runtime does the actual freeing of memory.
objective-c的内存管理使用的是引用计数。你必须维护你的引用栈,并在运行时自行释放内存。
In simplest terms, you alloc an object, maybe retain it at some point, then send one release for each alloc/retain you sent. So if you used alloc once and then retain once, you need to release twice.
比如说,你alloc了一个对象,或许也retain了他,然后你需要去release掉每一个你alloc/retain的对象。如果你使用alloc和retain各一次,那你必须release2次。
That's the theory of reference counting. But in practice, there are usually only two reasons to create an object:
只有两种情况你需要去创建一个对象:
- 保证其是一个可用常量
- 在方法里单独使用
1. To keep it as an instance variable
2. To use temporarily for single use inside a functionIn most cases, the setter for an instance variable should justautorelease the old object, and retain the new one. You then just make sure to release it in dealloc as well.
通常,setter一个变量的同时需要去autorelease一个旧对象,和retain新的对象。你需要保证在dealloc的时候释放它。
So the only real work is managing local references inside a function. And there's only one rule: if you create an object with alloc or copy, send it a release or autorelease message at the end of the function. If you create an object any other way, do nothing.Here's the first case, managing an instance variable:
- (void) setTotalAmount: (NSNumber*)input
{
[totalAmount autorelease];
totalAmount = [input retain];
}
- (void) dealloc
{
[totalAmount release];
[super dealloc];
}
Here's the other case, local references. We only need to release the object created with alloc:
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];
// only release value1, not value2
[value1 release];
And here's a combo: using a local reference to set an object as an instance variable:
NSNumber* value1 = [[NSNumber alloc] initWithFloat:8.75];
[self setTotal:value1];
NSNumber* value2 = [NSNumber numberWithFloat:14.78];
[self setTotal:value2];
[value1 release];
Notice how the rules for managing local references are exactly the same, regardless of whether you're setting them as instance variables or not. You don't need to think about how the setters are implemented.
If you understand this, you understand 90% of what you will ever need to know about Objective-C memory management.
learn objetive-c的更多相关文章
- Atitit learn by need 需要的时候学与预先学习知识图谱路线图
Atitit learn by need 需要的时候学与预先学习知识图谱路线图 1. 体系化是什么 架构 知识图谱路线图思维导图的重要性11.1. 体系就是架构21.2. 只见树木不见森林21.3. ...
- Python 爬取所有51VOA网站的Learn a words文本及mp3音频
Python 爬取所有51VOA网站的Learn a words文本及mp3音频 #!/usr/bin/env python # -*- coding: utf-8 -*- #Python 爬取所有5 ...
- [转载]VIM 教程:Learn Vim Progressively
文章来源:http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/ Learn Vim Progressively TL ...
- some tips learn from work experience
1.you can't avoid office politics 2.you'll never have a job which you "can't quit" - if yo ...
- Java-集合(没做出来)第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn reverseL
没做出来 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.a ...
- Learn RxJava
Learn RxJava http://reactivex.io/documentation/operators.html https://github.com/ReactiveX/RxJava/wi ...
- ANSI Common Lisp Learn
It has been a long time that I haven't dealt with my blog. On one hand I was preparing the exams.On ...
- [Notes] Learn Python2.7 From Python Tutorial
I have planed to learn Python for many times. I have started to learn Python for many times . Howeve ...
- 十分钟入门less(翻译自:Learn lESS in 10 Minutes(or less))
十分钟入门less(翻译自:Learn lESS in 10 Minutes(or less)) 注:本文为翻译文章,因翻译水平有限,难免有缺漏不足之处,可查看原文. 我们知道写css代码是非常枯燥的 ...
- Learning How To Learn
1.Practice 2.memory every week for from working memory to long tern memory 3.sleep 4.running promote ...
随机推荐
- Controller和View的交互
Controller和View的交互 目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI ...
- word 一些有用的技巧
为了能够word入代码,而且具备代码高亮显示功能.这里我提供一个工具------Notepad++,它具备一般文本的功能,且具备编写代码的功能. 包含代码排版,高亮显示,加入和删除凝视等. 在 语 ...
- 回想一下著名的BigTable论题
GFS捕捉一些业务场景的分布式文件系统的需求.很自然.此外还有一些与他们一些业务或依赖于文件系统是不那么容易,他们需要一个分布式数据库系统. BigTable那是,Google结构化数据处理的需求而产 ...
- winhec
#winhec# 开发人员刷屏看点 (视频) 今天大家已经被winhec刷屏了,本来不想写这篇了,但看了所有的文章,大家关注的都是windows 10的那些新功能,小米win10刷机,联想千元手机,小 ...
- installshield制作的安装包卸载时提示重启动的原因以及解决办法
原文:installshield制作的安装包卸载时提示重启动的原因以及解决办法 有时候卸载installshield制作的安装包程序,卸载完会提示是否重启电脑以完成所有卸载,产生这个提示的常见原因有如 ...
- ASP.Net TextBox控件只允许输入数字
原文:ASP.Net TextBox控件只允许输入数字 1.1.在Asp.Net TextBox 控件的 OnKeyPress 事件中指定输入键盘码必须为数字: <asp:TextBox ID= ...
- canvas绘制自定义的曲线,以椭圆为例,通俗易懂,童叟无欺
本篇文章,将讲述如何通过自定义的曲线函数,使用canvas的方式进行曲线的绘制. 为了通俗易懂,将以大家熟悉的椭圆曲线为例,进行椭圆的绘制.至于其他比较复杂的曲线,用户只需通过数学方式建立起曲线函数, ...
- Cacti+Nagios监控平台完美整合
Cacti+Nagios监控平台完美整合 本博文出自51CTO博客吴光科博主,有任何问题请进入博主页面互动讨论!博文地址:http://wgkgood.blog.51cto.com/1192594/1 ...
- CSS学习笔记之CSS的继承、层叠和特殊性
继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代.比如下面代码:如某种颜色应用于p标签,这个颜色设置不仅应用p标签 ...
- leetcode第30题--Next Permutation
problem: Implement next permutation, which rearranges numbers into the lexicographically next greate ...