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 ...
随机推荐
- bzoj 2655 calc —— 拉格朗日插值
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2655 先设 f[i][j] 表示长度为 i 的序列,范围是 1~j 的答案: 则 f[i][ ...
- AJAX 方式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- pcieport 0000:00:1c.5: PCIe Bus Error
进入Linux系统 root身份 编辑/etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="quiet" 将quiet改为 pci=nomsi ...
- sublime入门文章
http://www.iplaysoft.com/sublimetext.html http://code-tech.diandian.com/post/2012-07-18/40030958791 ...
- Linux之解决每次git pull/git push都需输入密码设置
操作命令: //执行这两条命令cd / git config --global credential.helper store 执行完命令之后会在.gitconfig文件中多加红色字体 [user] ...
- apache2.4.35 403 forbidden 解决办法
- Lightoj1015【基础题】
题意: 计算输入数>0的所有和: 思路: 直接干... #include<cstdio> #include<queue> #include<map> #inc ...
- unity gl 画线
using UnityEngine; using System.Collections; public class TGLLine : MonoBehaviour { private static M ...
- cogs 610. 数对的个数
610. 数对的个数 ★★ 输入文件:dec.in 输出文件:dec.out 简单对比时间限制:1 s 内存限制:128 MB Description出题是一件痛苦的事情!题目看多了也 ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 经典面试题
1.描述Cookie的作用 Cookie是网站保存在浏览器客户端的信息,也就是说保存在访客的机器里的变量,一般随着HTTP头发送到客户端.在Cookie生效之后及失效之前,客户每次发出页面请求的时候, ...