Objective-C 简明教程

本文假定读者具备c语言或者其他语言的背景,快速上手Objective-C,或做参考之用。

基础

C语言的扩展

Objective-C很大程度上兼容C语言,是C语言的扩展,所有以@开头的语言,都是扩展语法。在Objective-C中写C/C++是很容易的事情,只需要使用.cpp文件即可,Objective-C完全兼容。虽然OC是兼容C++的,但如果使用后缀m的文件编译,会找不到标准stl库,需要修改m后缀为mm。

Hello World

#import <Foundatioin/Foundation.h>

int main(int argc, const char * argv[])
{
    NSLog(@"Hello, World!");
    return (0);
}

Objective-C头文件以.h结尾,源文件以.m结尾。

注释

Objective-C 注释与 C++ 相同,符号: // 或者 /* */

导入

与C语言中的 #include <> 相对应的导入 #import <>

基本类型

Objective-C 中的基本类型同C,包括 bool, char, int, long, float, double, int 等。另外,在Foundation库中,这些类型还定义了别名,NSInteger对应有符号整数,NSUInteger对应无符号整数,CGFloat对应浮点数,BOOL对应布尔值。

数字对应的对象还有 NSNumber,可以跟基本的数字类型相互转化,详细信息可参阅 NSNumber Class Reference

字符串

常量字符串可以用@""结构表示,另外变量使用NSString表示不可变字符串 ,NSMutableString表示可变字符串。具体NSString和普通C字符串的转换,可参阅NSString Class Reference

数组

之前提到的,在Objective-C中可以无障碍使用C语言的数据,不过OC还提供了数组类 NSArrayNSMutableArray,前者是不能修改的数组,后者支持增删操作,具体用法示例如下。

插入操作:

NSMutableArray * array = [NSMutableArray arrayWithCapacity:50];
[array addObject:[NSNumber numberWithUnsignedLongLong:123]];
[array addObject:[NSNumber numberWithUnsignedLongLong:456]];

遍历操作:

NSLog(@"Array Size: %u", (int)[userIdList count]);

// method one
for(int i=0;i<[array count];i++)
{
	NSLog(@"%@",[array objectAtIndex:i]);
}

// method two
id ob;  
NSEnumerator *enumerator = [array objectEnumerator];
while(ob=[enumerator nextObject])
{
	NSLog(@"%@",ob);
}

// method three
for (NSNumber *num in array) {
	if ([num isKindOfClass:[NSNumber class]]) {
		NSLog(@"Elem: %llu", [num unsignedLongLongValue]);
	}
}

可以看出,NSArray可以插入任何对象,遍历可使用isKindOfClass识别哪种数据类型。详细的操作可参照NSMutableArray Class Reference

面向对象

interface

@interface Circle : NSObject
{
    ShapeColor fillColor;
}

- (void) setFillColor : (ShapeColor) fillColor;
- (void) draw;

@end
  • 程序开始 @interface 表示C的扩展语法,表示接口,继承自NSObject
  • ShapeColor fillColor; 声明了成员
  • - (void) draw;表示方法,前面的括号中表示方法的返回类型
  • - (void) setFillColor : (ShapeColor) fillColor; 冒号后面的部分,表示有一个参数 fillColor,类型是ShapeColor

方法调用

Objective-C 调用对象方法的基本语法如下:

[object method];
[object methodWithInput:input];

同样可以调用类的方法:

id myObject = [NSString string];

其中id表示myObject类型,可以承载任何对象。

在很多语言中支持嵌套调用,如function1 ( function2() );,Objective-C中可以同样可以写为:

[NSString stringWithFormat:[prefs format]];

多参数调用:

// 声明:-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];

implementation

之前的interface只是声明了接口,具体的实现如下:

@implementation Circle

- (void) setFillColor: (ShapeColor) c
{
    fillColor = c;
}

- (void) draw
{
    NSLog(@"drawing");
}

@end

解释:

  • 开始 @implementation Circle 表示为某个类提供代码。
  • 接下来是方法定义,fillColor = c 隐含 self->fillColor,表示当前对象的成员,调用方法时,circle setFillColor: kRedColor,方法将circle作为self参数进行传递。

属性

@interface属性定义:

// 头文件
@interface TestMessage : NSObject {
    NSMutableArray * elems;
}

@property(nonatomic,retain) NSMutableArray* elems;
@end

// 实现文件
@implementation IMMessage

@synthesize elems;

@end

关键字@property@synthesize含义如下:

// 头文件中:
@property int count;

// 等效为声明两个方法:
- (int)count;
- (void)setCount:(int)newCount;

// 实现文件中:
@synthesize count;

// 等效两个方法的实现
- (int)count
{
	return count;
}
-(void)setCount:(int)newCount
{
	count = newCount;
}

声明property的语法格式为:@property (参数1,参数2) 类型 名字;

参数的含义如下:

readwrite: 产生setter\getter方法
readonly: 只产生简单的getter,没有setter。
assign: 默认类型,setter方法直接赋值,而不进行retain操作
retain: setter方法对参数进行release旧值,再retain新值。
copy: setter方法进行Copy操作,与retain一样
nonatomic: 禁止多线程,变量保护,提高性能

实例化

对象的实例化:shape = [Circle new];

私有成员

对于私有变量,可以在 .m文件中声明一个 name 私有变量:

@interface Circle (){
    NSString* name;
}

对于私有方法,可以实现为:

@interface Circle (Private)
- (NSString*) GetName;
@end

@class

当两个类有循环依赖,如A类引用到B,B类又引用到A,import的时候没办法把两个类都放到自身前面,无法编译通过,这事可以A类中使用@class B来声明有一个类B,具体实现在其他地方,来解决循环依赖问题。

高级特性

selector

Objective-C中的方法调用就是消息传递,除了使用[]来传递消息以外,还有一种在运行期间进行消息传递的方法,就是selector方式,不同参数的消息传递如下:

// 无参数
- (void) fooNoInputs {
	NSLog(@"Does nothing");
}

[self performSelector:@selector(fooNoInputs)];

// 一个参数
- (void) fooOneIput:(NSString*) first {
	NSLog(@"Logs %@", first);
}

[self performSelector:@selector(fooOneInput:) withObject:@"first"];

// 多个参数
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
	NSLog(@"Logs %@ then %@", first, second);
}
[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];

另外,在selector中可以使用onThread参数指定所执行方法的线程。

内存管理

在之前的OC版本中,需要对象操作allocrelease等手工进行分配释放,一旦管理不善,容易出现内存泄漏或者崩溃。在Xcode 4.2中,增加了自动引用计数Automatic Reference Counting, ARC,不需要开发者考虑release的问题,详情可参考理解 Objective-C 的 ARC

参考资源

Built with Hugo
主题 StackJimmy 设计