现在的位置: 首页 > 综合 > 正文

[objective-c]教程一—–objective-c 类和方法

2013年07月14日 ⁄ 综合 ⁄ 共 7228字 ⁄ 字号 评论关闭
文章目录

改定履历:

2012-05-10-------------新建文本文档

正文:

本文原文地址

Objective-C 类

Objective-C 类的 interface

1. 声明实例变量和公有方法:

MyString.h

#import <Cocoa/Cocoa.h>

@interface MyString : NSObject {
  // Declare instance variables
  NSString* value;
}

// Declare methods
- (NSString*) value;
- (void) setValue: (NSString*)input;

+ (NSString*) append:(NSString *)fromString target:(NSString *)toString;
@end

2. MyString类继承了预先定义的顶级objective-c类NSObject(根类)

※ NSObject类是objective-c基础框架的根类

※ 最佳实践;应用对象都应该是NSObject的子孙.

@interface MyString : NSObject {

3. 符号"+"的意思是,该方法是objective-c类方法

- (NSString*) value;

4. 符号"-"的意思是,该方法是objecitve-c实例方法.

- (NSString*) value;

5. 定义一个NSString指针类型的实例变量:

NSString* value;

※ "*"表示这是个指针类型.

※ 所有的objective-c对象变量都是指针类型.

※ 所有的实例变量缺省都是私有的,需要使用setter方法和getter方法访问实例变量.(译者注:缺省应该是保护的,作者的意思应该是在访问实例变量时不能直接引用).

※ 所有的实例变量初始化时都被置为nil.

6. 声明getter方法

- (NSString*) value;

※ 相比其它语言,这里的getter方法没有类似于"getValue"的前缀"get".

7. 声明setter方法:

- (void) setValue: (NSString*)input;

※ 以参数"input"来设置"value"的值.

8. 声明携带多个参数的访求:

+ (NSString*) append:(NSString *)fromString myTarget:(NSString *)toString;

※ objective-c处理多个参数与其它语言不同:

如同其它语言类似,上面的方法实际上是创建了一个名字为"append:myTarget:",携带参数"formString"和"toString"的方法.

obj.appendMyTarget(fromString, toString)

+ (NSString*) add:(NSString *)fromString value2:(NSString *)toString;

Objective-C 类实现(Implementation)

下面示例包含实现代码和私有方法:

MyString.m

#import "MyString.h"

@implementation MyString

- (NSString*) value {
    return value;
}

- (void) setValue: (NSString*)input
{
    [value autorelease];
    value = [input retain];
}

@end

Objective-C 方法(Methods)

1. 给objective-c对象发送消息:

● 在objective-c中发送消息和在JAVA中调用一个方法等价

// Equivalent to myObject.myMethod(); in Java
[myObject myMethod];

// Equivalent to myObject.myMethod2(v1); in Java
[myObject myMethod2:v1];

// Equivalent to String result = myObject.method3(); in Java
NSString* result = [myObject myMethod3];

● myMethod3返回了NSString类型指针

● 接收消息的对象被称为接收者.

2.给objective-c类发消息

// Similar to NSString result = NSString.string(); in Java
NSString* result = [NSString string];

● 发送消息给NSString的类方法string.

3. 发送携带多个参数的消息:

// Similar to obj.add(v1, v2); in Java
[obj add:v1 value2:v2];

● "v1"和"v2"是objective-c方法"add:value2"的两个参数.

Method Declaration

// Similar to add(String fromString, String toString) in Java
+ (NSString*) add:(NSString *)fromString value2:(NSString *)toString;

● 方法参数区分顺序:

// Invalid
[obj value2:v1 add:v2];

● 如果声明了参数的话,参数不能像PHP或Ruby那样可选或带有缺省值.

// Invalid
[obj value2:];

4. 携带变量参数的方法:

[obj myMethod:v1, v2, v3, v4];

5. 在另一个消息内发送消息:

[obj myMethod1:[obj2 m1]];

● myMethod1携带的参数来自于:

[obj2 m1]

另一种形式:

[[obj getObj2] myMethod]

6. 发送消息给自身:

[self method];

● 实例方法内部,"self"意思是实例本身.
● 类方法内部,"self"意思是类本身(self refers to the class object)

7. 使用self创建新实例:

+ (id)createNewInstance
{
    id newInstance = [[self alloc] init];
    return [newInstance autorelease];
}

● 子类可以继承该方法 ,但仍需设法用下面的方式创建类实例:

[self alloc]

8. 给父类发消息:

[super method];

属性(Properties)

1. Getter/Setter方法声明:

@interface MyString : NSObject
{
@private
int value;
}
- (int)value;
- (void)setValue:(int)v;
@end

2. objective-c提供了一种自动产生setter方法和getter方法的声明和实现的机制.

● 使用"@property"声明getter/setter方法

MyString.h

#import <Cocoa/Cocoa.h>

@interface MyString : NSObject {
@private
    NSString* value;
}
@property (retain) NSString* value;

@end

● 注意,getter方法和setter方法以下面几种方式之一实现:

○ 使用"@synthesize"自动产生getter和setter方法的实现.

MyString.m

@implementation MyString

@synthesize value;

@end

○ 使用携带等号的"@synthesize"

@synthesize value = _value;

○ 等价于:

@interface MyString : NSObject
{
@private
int _value;
}

@synthesize value;

○ 不使用@synthesize手动实现getter和setter方法:

#import "MyString.h"

@implementation MyString

- (int)value {
    return value;
}
- (void)setValue:(int)v {
    value = v;
}

@end

○ 重载由"@synthesize"创建自动产生的方法:

@implementation MyString

@synthesize myTextArray;

- (void)setMyTextArray:(NSMutableArray *)newArray {
    if (myArray != newArray) {
        [myArray release];
        myArray = [newArray mutableCopy];
    }
}

@end

● 使用符号"."来访问getter/setter方法:

obj1.value = @"Test value";
result = obj1.value;

调用getter方法,而不是直接访问实例变量:

self.value;

3. 使用不同的"getter/setter"方法名:

@interface MyString : NSObject
{
@private
int internal_value;
}
@property int value;
@end
@implementation MyString
- (int)value {
return internal_value;
}
...
@end

@synthesize value = internal_value;

(retain)会指示编译器在setter方法里自动的调用retain来增加引用计数

@property (retain) NSString* value;

@property其它选项:

1. 在setter方法里做一份输入参数"input"的拷贝,并赋值给v1:

@property (copy) NSString *v1;

2. 设置objective-c属性只读(只有getter方法而没有setter方法)

@property (readonly) NSString *v1;

3. 在分配(赋值)之前先对输入参数(input)retain

// Release the old value [value release];
// Retain the new value value = [input retain];
@property (retain) NSString *v1;

4. getter方法和setter方法不需要支持原子操作:

@property (nonatomic) NSString *v1;

● 原子操作(atomic)为多线程环境下访问属性提供支持,这个setter/getter方法操作总是原子的,并且会返回一个应得的值而非一个过渡值.

5. 在objective-c property中使用多个attribute

@property (retain, nonatomic) NSString *v1;

6. 拷贝数组对象需附加一些代码:

@property (nonatomic, copy) NSMutableArray *myTextArray;

● "copy"返回了collection(数组array)的不可变长版本.

如果要返回一个可变长数组:

@interface MyString : NSObject {
    NSMutableArray *myTextArray;
}
@property (nonatomic, copy) NSMutableArray *myTextArray;
@end

getter方法和setter方法的"."符号:

1. objective-c为访问实例变量,对getter和setter方法提供了特别的语法访问器:

obj1.value = @"Test value";
result = obj1.value;

● 这个语法仅用于getter和setter方法上.

● 下面是用于properties的典型示例:

obj1.amount += 10;

2. 类通过访问器来设置类实例:

self.value = @"Test value";

Objective-C type: id

1. objective-c预定义了一个ID类型,基本上所有objective-c对象都是ID类型:

id result = [NSString string];

● 任何对象都可以被指定为id类型.

● id类型意味着结果可以被引用,可以被指派为任意其它类型

id obj1 = [obj2 aMethod];
[obj1 someMethod];

因此,编译器不会去验证一个对象是否实现了一个特定的方法.

// Will not throw a compilationr error
[result someNonExistingMethod];

2. 如果返回值或参数没有明确声明类型,可假定其它为id类型.

- findMyObject:someParam;
- (id)findMyObject:(id)someParam;

objective-c的NSObject和id的不同

1. 声明一个object对象类型会把对象接口类的详细信息提供给编译器

2. 对id类型来说,只有在运行时(runtime)才能确定接口类(interface),和产生缺失的方法错误.

NSObject* obj = ...

NSObject对象是静态对象,调用不存在的方法会产生编译错误:

// Will throw a compilation error
NSObject obj1 = ...
[obj1 someMethodNotBelongToNSObject];

创建,初始化和释放(free)objective-c对象

创建和释放(free)objective-c对象

1. 为objective-c对象分配内存

[NSString alloc]

2. 为objective-c对象分配内存并初始化

NSString* obj1 = [[NSString alloc] init];

3. 释放(release)对象,包括一旦不会使用的内存

● release失败会导致内存泄露

[obj1 release];

● "init"方法返回的对象可能会和"alloc"返回的对象有所不同,所以应在同一行调用"alloc"和"init".

NSString* obj1 = [[NSString alloc] init];

初始化objective-c对象

初始化objective-c对象的实现代码:

- (id) init
{
    if ( self = [super init] )
    {
        [self setValue:@"Set Default Value"];
    }
    return self;
}

● 调用父类初始化器初始化"self".

● 使用"if",以确保返回有效的对象.

self = [super init] 

● "init"返回id类型

● 指派自身为"init"的返回值,因为该初始化器可能会返回不同于原始消息接收者的对象.

- (id) init
{
   // Do not use the setter method self.someInstanceVariable = ...
   someInstanceVariable = [[NSString alloc] init];
   ...
}

● "alloc"方法会增加引用计数

● 如果"init"方法使用了"setter"方法来设置实例变量,引用计数会再加1.

Objective-c自定义初始化器

1. 自定义init方法应以"init"前缀开始:

- (id) initWithCount:(int)count
NSString* obj1 = [[NSString alloc] initWithCount:30];

2. 在初始化方法里调用另一个初始化方法

- (id)initWithValue:(NSValue *)data {

    // init method may return a new object
    // assign the new object back to the self
    self = [super initWithValue:data];
    if (self) {
        value = [data retain];
    }
    return self;

3. 增加error处理代码:

- (id)initWithValue:(NSValue *)data {

    // release itself if data is nil
    if (value == nil) {
        [self release];
        return nil;
    }

    self = [super initWithValue:data];
    if (self) {
        value = [data retain];
    }
    return self;

(便捷构造器)Convenience Constructors

1. 在Cocoa框架中,某些类方法绑定了"alloc"和"init"方法.被称之为便捷构造器(convenience constructors)

NSSTring* s = [NSString sting];

// no need to call [s release];

● 便捷构造器的调用者并不拥有该对象,因为无须释放(release)它.

● 便捷构造器通常调用"autorelease",在整个调用链结束的时候释放对象.

2. 便捷构造器的实现例子:

+ (id) createNewInstance:(NSString*) value
{
    id newInstance = [[self alloc] init];
    [newInstance setValue:value];
    return [newInstance autorelease];
}

释放(free)objective-c对象(回收,de-allocate)

1. 回收(de-allocate)objective-c对象

- (void) dealloc
{
    [value release];
    [super dealloc];
}

● 如果需要,可release任意实例变量

● 调用父类的"dealloc"

● 如果垃圾回收机制有效的话,"dealloc"并不作用于对象(仅用于r Mac OS X).

●  "dealloc会在运行时释放(free)对象时调用.

●  当垃圾回收机制有效时,实现"finalize"方法(When garbage collection is enabled, implement the finalize method)

抱歉!评论已关闭.