Objective-C 基础

来源:互联网 发布:熊猫安卓手游直播软件 编辑:程序博客网 时间:2024/05/22 05:31

Objective-C是基于标准的ANSI C的一门面向对象语言。其语法和设计主要基于Smalltalk,所以有些类似,而且支持标准的C语言语法。

代码文件的类型有三种:[.h]头文件,[.m]C代码,[.mm]C++代码。

定义了一种新的调用头文件的方法#import,这样不会重复#include头文件,只在没有调用过的时候调用一次,类似于PHP的require_once。 
最常用的数据类型:字符串NSString 
Objective-C将字符串数据类型定义成为Class,支持可变长度的字符串,支持Unicode等等一些实用的方法。通过使用@标志符,可以方便的由字符串常量定义NSString对象。下面给出一些定义NSString的代码实例。 
NSString *string1 = @"const string"; 
NSString *string2 = [NSString stringWithFormat:@"%d %d %s", 1, 2, "hello string"]; 


类(Class) 
作为面向对象语言最基本也是最重要的数据类型,Objective-C当然不会不支持。Objective-C定义类的特点在于先在.h头文件里定义接口,然后在.m代码文件里实现


关于.h头文件的具体的语法看下面的图更直接一点。




关于.h头文件的具体的语法看下面的图更直接一点。



大家注意一下initWithUserName()方法的返回值的数据类型为id,是不是感觉这个一般的语言有点区别。其实,这种数据类型类似于C++的指针。在Objective-C里面仍然叫做指针类型。Objective-C的对象的定义,可以支持强类型的实例,以及弱类型的实例的定义。简单的说,强类型就是定义该实例的时候必须指明类的名字,弱类型就是没有指明类的名字。下面给大家看看实际的代码就会明白,定义这两者的时候的区别。 
MYHelloWorld *myHelloWorld1;        // 强类型(Strong typing) 

id            myHelloWorld2;        // 弱类型(Weak typing) 
顺别提一下,弱类型能给实现设计模式(Design Patterns)的时候带来很大的方便。


方法(Methods) 
方法Methods又可称为函数。在Objective-C里的类可以定义两种方法。一种是实例的方法,一种是类的方法。实例的方法局限于某个类的实例,也就是必须定义这个类的实例之后,才能被调用执行的方法。类的方法不需要创建实例,直接通过类的名称就可以被调用执行的方法。 
定义一个方法需要:方法名(一个或者多个关键字),返回值类型,参数类型和参数名。下面这的图详细的说明了如何定义一个实例的方法,其中负号[-]表示该方法为实例的方法,该方法的名称加上各个关键字包括冒号即为[insertValue:atIndex:]。




 
Objective-C调用方法是通过发送消息给对应的实例对象。发送消息的方式其实是和一般的编程语言一样就是调用实例对象的方法,Objective-C独特的地方就是方法的调用是通过一个方法名+零个或多个标示符+零个或多个参数,然而一般的编程语言只需要一个方法名+零个或多个参数就可以了。Objective-C里面之所以把调用方法称为发送消息,大概是因为所有的消息发送之后都是动态传递给实例对象的。并且,如果一个子类定义了一个和父类相同方法名+标示符的方法之后,子类会先收到该消息,然后选择性的是否继续将该消息传递给父类。

 
发送消息是通过一对方括号[]来实现的。在括号的里面,实例对象在左边,消息以及参数等的定义在右边。例如: 
[anObject insertValue:anObj atIndex:1]; 
为了避免生成多余的临时变量,Objecttive-C容许直接使用消息的结果。如下例: 
[[anObject getArray] insertValue:[anObject getValueToInsert] atIndex:0]; 


类的方法,类似于静态方法(Static Function),常用于作为工厂模式中用来生成新的实例。定义的时候和实例的方法有区别的地方就是开头的符号为加号[+]。调用的类的方法和调用(Static Function)基本相同,直接通过类名就可以,如下例: 
NSMutableArray*   myArray = nil;    // nil等同于通常的NULL  
// 创建一个动态数组,并且制定最初的大小 
myArray = [NSMutableArray arrayWithCapacity:19]; 


属性 
属性是一个可以取代方法的方便符号。在类中声明定义属性时,并不创建新的实例,就是一个能够方便快捷的用来访问实际已经存在的变量的方法。也就是说,属性其实并没有真正的存储任何数据。 其实属性是可以让你在编写代码时减少影响效率的冗余代码。简单的说属性要比getter和setter方法快。 
属性还可以定义一些访问该属性时的限制或者如何获取该属性,例如指定copy用来复制该属性,readonly用来指定该属性只读。

@property BOOL workFlag; 
@property (copy) NSString* oString;  // 通过复制来使用该属性. 
@property (readonly) UIView* oView;  // 定义一个类似于getter的属性. 
调用某实例的属性有两种方法,一种是通过括号,和调用方法类似,另外一种是通过点符号[.]。第二方法比较方便,也符合大多数开发人员的习惯。 
    // 第一种调用方法 
    [myObject setFlag:YES]; 
    CGRect   viewFrame = [[myObject rootView] frame];      // 第二种调用方法     myObject.flag = YES; 
    CGRect   viewFrame = myObject.rootView.frame; 


协议和委托(Protocols and Delegates) 
Objective-C中的协议(Protocol)类似于常用的接口,协议(Protocols)中定义的方法,在类中实现。 
@protocol MyFirstProtocol 
    - (void)myFirstProtocolMethod; @end 
在iPhone OS中,协议(Protocol)通常用来实现委托对象(Delegate Object)。委托对象(Delegate Object)一般用来自己定义行为或者动作,也就是调用自己定义方法,但自己不实现该方法,委托其它的类来实现该方法。 
UIApplication类就是一个典型的例子。UIApplication类中定义了一个应用程序应有的行为或者动作。而不是强制让你的UIApplication子类去接受当前应用程序的状态消息并做出相应处理。UIApplication类通过调用特殊的方法,来传递这些消息给它的委托对象。这个委托对象通过实现名为UIApplicationDelegate的协议(Protocol),之后就可以接受到当前应用程序的状态消息并做出相应处理。比如内存不够的错误,应用程序被中断等重要消息。 下面给出一段关于HelloWorld的实例代码:

//main.m #import  
int main(int argc, char *argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];     int retVal = UIApplicationMain(argc, argv, nil, nil);     [pool release];     return retVal; }


#import,NSLog(),数据类型                                       


(1)在object-c中,用#import来代替C语言中的#include;

在一般的头文件中都会用#import<Foundation/Foundation.h>;

Foundation框架是一个处理用户界面之下的层中的特性,Foundation为cocoa框架的子集,cocoa框架还包括Application Kit框架。

 

(2)NSLog

此命令是向控制台显示输出语句,跟c语言的printf()很相似,和java中的Log4j类似,比如:

NSLog(@”Hello World!”);则是在控制台输出HelloWorld!双引号中的字符串前有一个@符号,这表示引用的字符串应该作为Cocoa的NSString元素来处。前面的NS代表你这个函数是来自Cocoa而不是其他工具包,这是苹果公司的习惯问题,为了保存之前代码的兼容性,才继续采用NS前缀。

 

(3)数据类型

object-c支持的类型有:

布尔类型(boolean):他具有YES和NO两个值,与c语言的true和false类似。

例如:Booleanrunning;

对象类型:在object-c中,一个对象包含了数据和一组操作,这组操作可以使用或是修改对象的数据。

id:在object-c中,对象标识被作为一个特殊的数据类型:id。这个数据类型定义为引用对象的指针。实际上是指向对象实例变量的指针。

例如:idlight;

id和对象类型的比较

1,id关键字在编译时不被检查,而NSObject在编译时会被检查是否被调用一些错误方法。

2,id可以是任何对象,包括非NSObject对象

3,定义id的时候不使用*,NSObject却需要。

 

字符串类型(NSString):

例如:NSString*aString = @“我是一个NS字符串”;

或者可以这样创建: NSString *aString = [[NSString alloc] initWithFormat:@"这也是个NS字符串!"];

*initWithFormat是其中一个初始化方法,常用的还有

//从一个文件读取需要的内容

- (id)initWithContentsOfFile:(NSString *)pathencoding:(NSStringEncoding)enc error:(NSError **)error

//从一个地址读取需要的内容

 -(id)initWithContentsOfURL:(NSURL *)urlencoding:(NSStringEncoding)enc error:(NSError **)error

*以上方法得到的NSString的retain值为1,所以要记得release掉(retain和release下次讲)

 

其他类型则与c语言具有较大的相似性


property,assign,copy,retain,release              


例子:

@property(nonatomic,retain) NSString *aString;


property:属性的定义,相当于C语言的setter和getter方法。

assign:简单的赋值,不更改索引的计数。

copy:建议一个索引计数为1的对象,然后释放旧对象;

retain:释放旧对象,将旧对象的值赋予新对象,再增加新对象的索引计数1。

 

针对具体的数据类型在属性定义应该这样选择:

使用assign:对基础的数据类型,比如NSInterger,CGFloat和C数据类型(int,float,double,char等等)。

使用copy:针对NSString;

使用retain:针对NSObject及其子类。

使用nonatomic:单线程,防止在写未完成的时候被另外一个线程读取,造成数据读取出错。

使用release:基于一般的初始化,使用alloc和init关键词初始化的,要在恰当的地方release掉,全局变量在dealloc方法里面release,常规变量在不需要的时候就要释放掉。


@interface,@implementation                                    

1.@interface

在java等语言编程中,创建类都是用class,但在object-c中,用@interface。

例子:

@interface circle :NSObject    //定义名为circle的类,继承自NSObject

{

            ShapeColorfillColor;//定义ShapeColor类型的实例变量 fillColor;

            Shapebounds;//定义Shape类型的实例变量 bounds;

}

- (void)setFillColor:(ShapeColor)fillColor;//定义名为setFillColor的方法

 

 

2.@implementation

在object-c中,@interface定义放在.h文件中,而@implementation放在.m 文件,是.h文件的详细实现。

例子:

@implementation circle //结尾没有分号。

 

- (void)setFillColor:(ShapeColor)c

{

            fillColor= c;//把参数c赋值给@interface中定义的fillColor;

}

3.实例化对象

为了使用我们已经定义的类,我们需要实例化对象,我们可以在我们创建的文件中的main()函数实例化:如下

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

{

            idshapes[3];//定义id类型数组

 

            shapes[0]= [circle new];//实例化circle并赋值给shapes

            [shapes[0]setFillColor:kRedColor];//调用方法进行赋值

}


预定义,条件编译,数组                                             

1.     预定义:#define

在object-c中,跟C语言一样都是采用#define才使用,但末尾是没有分号的;

例子:

#define PI 3.14

在之后即可引用,这点在iphone开发中一定每个组建的tag非常好用,并且可以集合放一个定义文件中。

2.     条件编译:#ifdef,#end,#elseif

#ifdef,#else,#endif如我们常识认为的那样,程序会根据判断条件处理或者忽略某一个程序段。

例子:

#ifdef MAC_OS_X

#  define DATADIR “/uxnl/data”

#else

#  define DATADIR “\usr\data”

#endif

3.     数组

在object-c中,C语言的数组格式初始化和引用都能够用,但在object-c中不提倡使用。

(1)不可变数组:NSArray

初始化: 

NSArray*array=[[NSArray alloc] init];

相同的初始化方法还有:

initWithArray;

initWithContentsOfFile;

initWithContentsOfURL;

initWithObjects;

同样还可以通过如下方法创建一个数组:

arrayWithArray;

arrayWithContentsOfFile;

arrayWithContentsOfURL;

arrayWithObject;

arrayWithObjects;

其他详细的可以参考IOS开发者文档。

(2)可变数组:NSMutableArray

NSMutableArray是在开发中最常用的数组,常用如下声明:

初始化:

NSMutableArray *mutableArray =[[NSMutableArray alloc] init];

还有:

arrayWithArray:array;

arrayWithObjects:;

arrayWithCapacity;

initWithCapacity;

另外还有增加元素的删除元素的方法,如下:

addObject:

addObjectFromArray:

insertObject:atIndex:

removeObject:

removeObjectAtIndex:

具体的可以参照IOS开发文档

(3)字典:NSDictionary

 初始化的方法有:

NSDictionary *dictionary = [NSDictionary alloc] initWithObjectsAndKeys:
@"number1",@"1",@"number2",@"2",@"number3",@"3",nil];
同样也有多种相似的初始化方法,但开发中最常用的是:

  + (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys

 

  这个可以根据键值对对相同的键值进行配对,对存储成对的数据非常管用。

  相同的字典也有可变字典:NSMutableArray.这个属性的具体情况类似NSMutableArray,具体可以查看IOS开发文档。



0 0
原创粉丝点击