iPhone学习笔记1

首先肯定是先学习Objective-C语言了。Objective-C历史什么的就不用在这里详谈了,就只谈谈语法和使用吧。

一、Objective-C与C++的区别

Objective-C是c语言的严格母集合,意思就是任何c语言程序经过Objective-C编译器都不需要做任何修改。与c++不同,c++只是一种为了兼容c语言而设计的面向对象的语言,从某种意义上来说是不同与c语言的,而Objective-C是在C语言基础上添加了扩展而创造出来的能够创建和操作对象的一门新的程序设计语言,gcc原生支持Objective-C。

Objective-C也是从一个main函数开始:

int main(int argc, char *argv[]){

     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

     NSLog(@"Hello World!");

     [pool drain];

return 0;}

Objective-C最大的特点是函数是以发送消息的形式工作,而且类与函数的关系比较松散,调用函数,则向该类发送消息,类不保证会有所回应,如果无法回应,程序只会以抛异常的方式处理,而不会死掉。而c++则不同,一个类与其方法间在编译期间已经联系在一起,不可能调用该类种不存在的方法。由于Objective-C是动态解析,所以其速度比c++的vitural function慢3倍,不过经过imp快取改善,已经较其快50%了。

Objective-C与c++的区别之一就是Objective-C不支持多重继承,和java一样,以协议的方式解决。Objective-C中有两种协议:为特定目的设定的“非正式协议”,以及由编译器保证的“正式协议”。

二、Objective-C语法

1、类

Objective-C强制要求将类分隔成interface和implementation两块,分别以@interface,@end和@implementation,@end标记。

如下:

@interface MyObject : NSObject {

    int memberVar1; // 成员变量

    id memberVar2;}

    +(return_type) class_method; // 类函数类似c++static函数

    -(return_type) instance_method1; // 成员函数

    -(return_type) instance_method2: (int) p1;-(return_type) instance_method3: (int) p1 andPar: (int) p2;

@end

翻译成c++:

class MyObject : public NSObject {

    int memberVar1;

    void * memberVar2;

    public: static return_type class_method();

    return_type instance_method1();

    return_type instance_method2( int p1 );

    return_type instance_method3( int p1, int p2 );

}

执行块:

@implementation MyObject

+(return_type) class_method {

.... //method implementation

}

-(return_type) instance_method1 {

....

}

-(return_type) instance_method2: (int) p1 {

....

}

-(return_type) instance_method3: (int) p1 andPar: (int) p2 {

....

}

@end

一般inerface放入.h文件。执行块放入.m文件,类似c++中以在cpp文件中的使用类名加::符号来外部化类函数的方式。

创建一个类对象方法:

(1)MyObject * my = [[MyObject alloc] init];    //alloc是在内存分配空间,init可以类似c++中的constructor函数一样被重写,实现初始化。

(2)MyObject * my = [MyObject new];            //Objective-C2.0

类方法调用:

从上面可以看出是[类名(或者类对象名)类方法(或者类成员函数)];

2、 协议

正式协议则类似于Java中的"接口",它是一系列方法的列表,任何类都可以声明自身实现了某一个或一些协议。在Objective-C 2.0之前,一个类必须实现它声明符合的协议中的所有方法,否则编译器会报告一个错误,表明这个类没有实现它声明符合的协议中的全部方法。Objective-C 2.0版本允许标记协议中某些方法为可选的,这样编译器就不会强制实现这些可选的方法。

非正式协议即为一个类可以选择性实现的一系列方法的列表。

语法

@protocol Locking

- (void)lock;- (void)unlock;

@end

表明有“锁”的抽象观念。以下声明表明了这个类实现了协议Locking:

@interface SomeClass : SomeSuperClass <Locking>

@end

3、动态类型

- setMyValue:(id) foo;

该函数可以发送消息到任意类实例。

- setMyValue:(id <aProtocol>) foo;

该声明表示“foo”可以是任何类的实例,但它必须符合“aProtocol”协议。

- setMyValue:(NSNumber*) foo;

该声明表示“foo”必须是“NSNumber”的实例。

静态类型信息也可以应用到变量上,这些信息会在编译期被检查。以上三种声明提供了一个比一个明显的类型信息。这三种声明在运行时是等同的,但附加的类型信息允许编译器在编译时检查变量类型,并在类型不符的情况下提出警告。

4、转发

  • 转发方法:
    - (retval_t) forward:(SEL) sel :(arglist_t) args; // with GCC
    - (id) forward:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
    
  • 响应方法:
    - (retval_t) performv:(SEL) sel :(arglist_t) args;  // with GCC
    - (id) performv:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
    
重写forward方法

例子

这里包括了一个演示转发的基本概念的程序示例。


Forwarder.h

#import <objc/Object.h>

@interface Forwarder : Object{

     id recipient; //该对象是我们希望转发到的对象。

}

@property (assign, nonatomic) id recipient;

@end



Forwarder.m

#import "Forwarder.h"

@implementation Forwarder

@synthesize recipient;

- (retval_t) forward: (SEL) sel : (arglist_t) args{ /* *检查转发对象是否响应该消息。 *若转发对象不响应该消息,则不会转发,而产生一个错误。 */

    if([recipient respondsTo:sel])

    return [recipient performv: sel : args];

     else return [self error:"Recipient does not respond"];

}



Recipient.h

#import <objc/Object.h>

// A simple Recipient object.

@interface Recipient : Object

- (id) hello;

@end



Recipient.m

#import "Recipient.h"

@implementation Recipient

- (id) hello{

    printf("Recipient says hello!\n");

    return self;

}

@end



main.m

#import "Forwarder.h"

#import "Recipient.h"

int main(void){

Forwarder *forwarder = [Forwarder new];

Recipient *recipient = [Recipient new];

forwarder.recipient = recipient;

//Set the recipient. /* *转发者不响应hello消息!该消息将被转发到转发对象。 * (若转发对象响应该消息) */

[forwarder hello];

return 0;

}


5、类别

新建一个类文件Arithmetic.h和Arithmetic.m

@interface Integer (Arithmetic)

。。。

@end


@implementation Integer (Arithmetic)

。。。

@end

在执行体中的函数如果想使用则可以import该h文件,如果不想使用该功能则可以简单不编译该文件即可。

命令:gcc -x objective-c main.m Integer.m Arithmetic.m Display.m -lobjc

使用了该功能。

6、属性

Objective-C 2.0引入了新的语法以声明变量为属性。

语法定义:

@interface Person : NSObject {

@public

    NSString *name;

@private

    int age;

}

@property(copy) NSString *name;

@property(readonly) int age;

-(id)initWithAge:(int)age;

@end

属性的存取方法由@synthesize关键字来实现,它由属性的声明自动的产生一对存取方法。另外,也可以选择使用@dynamic关键字表明存取方法会由程序员手工提供。

@implementation Person

@synthesize name;

@dynamic age;

-(id)initWithAge:(int)initAge{

    age = initAge; // 注意:直接赋给成员变量,而非属性

    return self;

}

-(int)age{

    return 29; // 注意:并非返回真正的年龄

}

@end

如果只定义了变量 NSString *name,而没有@property。。。name,则使用self.name不能编译通过;只定义@property。。。name,如果使用name,会编译不通过,name未定义,如果使用self.name是可以编译通过的,但是使用self.name会直接抛异常,程序退出;定义了@property。。。name,以及@synthesize,则直接调用name不会有问题,但是使用self.name则会导致程序直接退出;若同时定义变量和@property,@synthesize,则直接调用变量和使用self调用变量是效果相同的。

7、垃圾回收

gcc打开垃圾收集的参数是:-fobjc-gc

不过iphone并不支持垃圾收集。而且效率肯定会有所降低,最好使用旧的计数方式手工回收。

8、快速枚举

// 使用NSEnumerator

NSEnumerator *enumerator = [thePeople objectEnumerator];

Person *p;

while ( (p = [enumerator nextObject]) != nil ) {

    NSLog(@"%@ is %i years old.",[p name], [p age]);

}

// 使用依次枚举

for ( int i = 0; i < [thePeople count]; i++ ) {

    Person *p = [thePeople objectAtIndex:i];

    NSLog(@"%@ is %i years old.", [p name], [p age]);

}

// 使用快速枚举

for (Person *p in thePeople) {

    NSLog(@"%@ is %i years old.", [p name], [p age]);

}

快速枚举可以比标准枚举产生更有效的代码,由于枚举所调用的方法被使用NSFastEnumeration协议提供的指针算术运算所代替了。效率是不同的。


参考资料:

http://zh.wikipedia.org/wiki/Objective-C#.E5.8A.A8.E6.80.81.E7.B1.BB.E5.9E.8B



你可能感兴趣的:(iPhone学习笔记1)