Objective-C language
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.
Calling Methods
[object method];
[object methodWithInput:input];
output = [object methodWithOutput];
output = [object methodWithInputAndOutput:input];
id myObject = [NSString string];
In this example, it's obvious the object type will be an NSString, so we can change the type:
NSString* myString = [NSString string];
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
function1 ( function2() );
[NSString stringWithFormat:[prefs format]];
Multi-Input Methods
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];
Accessors
[photo setCaption:@"Day at the Beach"]; output = [photo caption];
Whenever you see code inside square brackets, you are sending a message to an object or a class.
Dot Syntax
photo.caption = @"Day at the Beach";
output = photo.caption;
Creating Objects
NSString* myString = [NSString string];
NSString* myString = [[NSString alloc] init];
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.
In some cases, you may use a different version of init which takes input:
NSNumber* value = [[NSNumber alloc] initWithFloat:1.0];

Basic Memory Management
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.
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];
There's more to learn about memory management, but it will make more sense after we look at a few more concepts.

Designing a Class Interface
The class interface is usually stored in the ClassName.h file, 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.
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
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 and photographer. Both are NSStrings, but they could be any object type, including id.
Finally, the @end symbol ends the class declaration.
Add Methods
#import <Cocoa/Cocoa.h> @interface Photo : NSObject {
NSString* caption;
NSString* photographer;
} - caption;
- photographer; @end
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
#import <Cocoa/Cocoa.h> @interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer; - (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input; @end
Class Implementation
#import "Photo.h" @implementation Photo - (NSString*) caption {
return caption;
} - (NSString*) photographer {
return photographer;
} @end
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];
}
- (void) setCaption: (NSString*)input {
caption = input;
}
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
- (id) init
{
if ( self = [super init] )
{
[self setCaption:@"Default Caption"];
[self setPhotographer:@"Default Photographer"];
}
return self;
}
This essentially just asks the superclass to do its own initialization. The ifstatement is verifying that the initialization was successful before trying to set default values.
Dealloc
- (void) dealloc
{
[caption release];
[photographer release];
[super dealloc];
}
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
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.

1. To keep it as an instance variable
2. To use temporarily for single use inside a function
In most cases, the setter for an instance variable should just autoreleasethe old object, and retain the new one. You then just make sure to release it in dealloc as well.
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];
}
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];
If you understand this, you understand 90% of what you will ever need to know about Objective-C memory management.
Logging
NSLog ( @"The current date and time is: %@", [NSDate date] );
Properties
Properties are a feature in Objective-C that allow us to automatically generate accessors, and also have some other side benefits. Let's convert the Photo class to use properties.
Here's what it looked like before:
#import <Cocoa/Cocoa.h> @interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- (NSString*) caption;
- (NSString*) photographer; - (void) setCaption: (NSString*)input;
- (void) setPhotographer: (NSString*)input; @end
#import <Cocoa/Cocoa.h> @interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
@property (retain) NSString* caption;
@property (retain) NSString* photographer; @end
Now let's take a look at the implementation of the class:
#import "Photo.h" @implementation Photo @synthesize caption;
@synthesize photographer; - (void) dealloc
{
[caption release];
[photographer release];
[super dealloc];
} @end
Accessors will only be generated if they don't already exist, so feel free to specify @synthesize for a property, then implement your custom getter or setter if you want. The compiler will fill in whichever method is missing.
There are many other options for the property declarations, but those are outside of the scope of this tutorial.
Calling Methods on Nil
This technique used by the frameworks in a number of different ways, but the main thing it means to you right now that you usually don't need to check for nil before calling a method on an object. If you call a method on nil that returns an object, you will get nil as a return value.
We can also use this to improve our dealloc method slightly:
- (void) dealloc
{
self.caption = nil;
self.photographer = nil;
[super dealloc];
}
Note that we're using the self.<var> syntax here, which means we're using the setter and picking up the memory management for free. If we just directly set the value like this, there would be a memory leak:
// incorrect. causes a memory leak.
// use self.caption to go through setter
caption = nil;
Categories
This is particularly useful because you can add methods to built-in objects. If you want to add a method to all instances of NSString in your application, you just add a category. There's no need to get everything to use a custom subclass.
For example, if I wanted to add a method to NSString to determine if the contents is a URL, it would look like this:
#import <Cocoa/Cocoa.h> @interface NSString (Utilities)
- (BOOL) isURL;
@end
Here's the implementation. Keep in mind this is not a good implementation of URL detection. We're just trying to get the concept of categories across:
#import "NSString-Utilities.h" @implementation NSString (Utilities) - (BOOL) isURL
{
if ( [self hasPrefix:@"http://"] )
return YES;
else
return NO;
} @end
NSString* string1 = @"http://pixar.com/";
NSString* string2 = @"Pixar"; if ( [string1 isURL] )
NSLog (@"string1 is a URL"); if ( [string2 isURL] )
NSLog (@"string2 is a URL");
Remember, when you make changes to a class using a category, it affects all instances of that class throughout the application.
Objective-C language的更多相关文章
- Automake
Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...
- 第十五次oo作业
作业十五 测试与正确性论证的效果差异 程序的测试需要通过输入特定数据等方式,检查程序是否和预期相同,因为测试不可能穷举,导致了不穷举的测试不可能验证程序是完全正确的,只能验证程序在测试时没有发生错误, ...
- NLP中的预训练语言模型(三)—— XL-Net和Transformer-XL
本篇带来XL-Net和它的基础结构Transformer-XL.在讲解XL-Net之前需要先了解Transformer-XL,Transformer-XL不属于预训练模型范畴,而是Transforme ...
- The Swift Programming Language 中文翻译版(个人翻新随时跟新)
The Swift Programming Language --lkvt 本人在2014年6月3日(北京时间)凌晨起来通过网络观看2014年WWDC 苹果公司的发布会有iOS8以及OS X 10.1 ...
- Artificial Intelligence Language
Artificial Intelligence Language Objective We know, a true AI program should have ability to underst ...
- Objective C静态代码扫描和代码质量管理 OClint + SonarQube
OClint是针对C, C++及Objective C代码的静态扫描分析工具,而SonarQube是一个开源的代码质量管理平台.本文将实现将OClint的扫描结果导入到SonarQube中,已实现对O ...
- C++ vs Objective C
oc Short list of some of the major differences: C++ allows multiple inheritance, Objective-C doesn't ...
- JavaScript Prototype in Plain Language
非常好的文章: http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/ jan. 25 2013 14 ...
- Objective -C Memory Management 内存管理 第一部分
Objective -C Memory Management 内存管理 第一部分 Memory management is part of a more general problem in pr ...
- A Pattern Language for Parallel Application Programming
A Pattern Language for Parallel Application Programming Berna L. Massingill, Timothy G. Mattson, Bev ...
随机推荐
- 运用Eclipse的Working Set,界面清爽多了
使用Eclipse的Working Set,界面清爽多了 想必大家的Eclipse里也会有这么多得工程...... 每次工作使用到的项目肯定不会太多...... 每次从这么大数量的工程当中找到自己要使 ...
- Linux 软链接 硬链接 ln命令(繁杂版)
注意:创建软连接的时候,要用绝对路径!!! 这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,具体用法是:ln - ...
- Linux useradd 添加用户
在 linux 中,如果我们想添加一个用户,那么使用的命令如下: 用户管理命令: useradd 基础的命令 命令名称:useradd 命令的所在路径:/usr/bin/useradd 执行权限:ro ...
- 浅谈SpringBoot核心注解原理
SpringBoot核心注解原理 今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到零配置 ...
- 4.2 手写Java PriorityQueue 核心源码 - 实现篇
上一节介绍了PriorityQueue的原理,先来简单的回顾一下 PriorityQueue 的原理 以最大堆为例来介绍 PriorityQueue是用一棵完全二叉树实现的. 不但是棵完全二叉树,而且 ...
- lightoj1004【基础DP】
从低端到顶端求个最大值: 思路: 基础DP,递推 #include<cstdio> #include<queue> #include<map> #include&l ...
- [Xcode 实际操作]七、文件与数据-(20)CoreML机器学习框架:检测和识别图片中的物体
目录:[Swift]Xcode实际操作 本文将演示机器学习框架的使用,实现对图片中物体的检测和识别. 首先访问苹果开发者网站关于机器学习的网址: https://developer.apple.com ...
- 编译keepalived 方法
作者的环境: redhat 6.5 64 位版 在编译keepalived 前,需要提前给环境安装两个依赖包--zlib和openssl 编译 zlib 库 参考作者之前的博客 http://www. ...
- 区间质数查询 luoguP1865
原题 https://www.luogu.org/problemnew/show/P1865 本来get到了一个很好的判断素数的方法 O(玄学常数)https://www.luogu.org/blog ...
- ADO学途 five day 连接数据库
用一个程序的目的就是为了方便对数据进行操作,没有数据的支持,程 序就成了一个空壳子.一般我们常用的数据库有三种mysql, SQL server, Oracle. C#中常用的就是SQL server ...