欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

objective-c,

来源: 开发者 投稿于  被查看 29811 次 评论:267

objective-c,


Objective-C基础教程1-6章节

最近不算很忙,又没有太多深入研究,按照惯例找一些没接触过的新东西看看学习学习,WiEngine,Box2d之后,这次轮到了Objective-C。Objectvie-C随着苹果设备的风靡,也是最热门的技术之一,无奈之前对C一直存在一些芥蒂,所以没有去接触,不过怎么说语言也是共通的,有些坎肯定还是要迈过的,特别是当下所谓跨Android/iPhone平台,其实都是用C++在开发,所以上上手也是很有必要。

下面是对看Objective-C基础教程1-6章后,对一些东西的笔记,并不是完整的教程,只是类似拾遗,将一些不同的,不熟悉的东西记下来(和之前Python笔记类似)

一切都源于Hello World 恒古不变的定律,熟悉一门语言结构最快也就是这个万能的程序了,Objective-C扩展名为.m(之后书中也有提到.mm就是C++风格)

 

Objective-c代码  
  1. #import <Foundation/Foundation.h>  
  2. int main(int argc, const char *argv[]){  
  3.     NSLog(@"Hello Objective-C");  
  4.     return (0);  
  5. }  

 

其中NSLog方法是Objective-C专属的一种类型,所有cocoa的对象都被冠以了NS前缀,作为区分。传入的参数@""表示字符串作为NSString被处理,程序其余部分和C类似,#import的含义也不言而喻

布尔值

Objective-C中的布尔变量有些许小的不同,参数类型为BOOL,值为YES/NO,其中YES为1,NO为0,占8位

需要注意的是,如果将一个int,short这样的值赋给BOOL,只有低位字节会发挥作用,这是特别要注意的,因为这意味着,并不是传统认为的,非零即为true

Objective-C中有一种特有的语法:[对象 操作] 这在之后会一直看到

关于Objective-C中的OOP

@interface

至少目前我还将其于java中的接口相类比,名称也一样,但是有人告诉我Objective-C中的interface并不同于接口,而类似于接口的Objective-C中有一个叫做协议的东西,这个以后看到了我会再加以对比区分

 

Objective-c代码  
  1. @interface Circle:NSObject  
  2. {  
  3.     ShapeColor color;  
  4.     ShapeRect bounds;  
  5. }  
  6. -(void) setFillColor: (ShapeColor) color;  
  7. -(void) setBounds: (ShapeRect) bounds;  
  8. -(void) draw;  
  9. @end  

 

以上就是标准的一个@interface定义,应该很好理解,Circle含有2个变量color,bounds,拥有3个方法

特别注意方法的申明方式 

(void) 表示返回类型 之后是方法名及参数

draw方法不含参数 也不用:

对于多个参数的方法申明

-(void) setTire: (Tire *) tire atIndex:(int) index;(这里的第二个参数看起来有些奇怪,但是在之后调用方法的过程中,atIndex会被用到)

Objective-C的方法调用使用了一种被称为中缀符的东西

看一下分别调用无参,1参和多参的语法

 

Objective-c代码  
  1. [circle draw];  
  2. [circle setFillColor:kRedColor];  
  3. [car setTire:tire atIndex:2];<span> </span>  

 

@implementation

与名字相同,实现,就是对@interface所申明内容的具体实现

 

Objective-c代码  
  1. @implementation  
  2. -(void) setFillColor:(ShapeColor c)  
  3. {  
  4.     color=c;  
  5. }  
  6. @end  

 

这里的color=c其实就相当于self.color=c(这里我又要做类比了,目前的认识self就相当于java中的this指针)

有了@interface和@implementation之后,我们对一个类(对象)的定义就算完成,那么如何实例化一个对象

 

Objective-c代码  
  1. id shapes[3];  
  2. shapes[0]=[Circle new];  
  3. [shpaes[0] setBounds:rect];  
  4. ...  

 

这里又看到一个新的东西id,它是一种指向某个对象的指针,目前为止只是看到这一种用法,也没有太多认识,简单的被我理解成了索引

之后看到了new对象的方法[Circle new],再之后是调用对象的方法设置具体的参数

继承

 

Objective-c代码  
  1. @interface Circle:Shape  

 

很简单的方法,Objective-C在继承规则上于java,C#无异,不允许多重继承,不过既然有接口(或者应该叫协议),那么自然同java一样,达到相同的目的自然不难,同样的,子类可以调用父类的方法,通过super,比如[super setColor:c];

Ojbective-C中的空值为nil

接下来 来看一个Car是被如何自动构建的

 

Objective-c代码  
  1. @implementation Car  
  2. -(id) init  
  3. {  
  4.     if(self=[super init]){  
  5.         engine=[Engine new];  
  6.         ...  
  7.     }  
  8.     return (self);  
  9. }  

 

这一段有些理解不能,在书中的注释中说到,这里指如果超类可以完成所需的一次性初始化,需要调用[super init]。init方法的返回值id描述了倍初始化的对象。将[super init]的结果赋给self是Objective-C的标准惯例。

Objective-C中一样有getter/setter方法,但是在命名规则上需要注意

 

Objective-c代码  
  1. -(Engine *)engine;  
  2. -(void) setEngine: (Engine *) engine;  

 

在set方法中 依然采取setXXX的方式 但是get方法则直接采用XXX 而非getXXX,以免混淆

拆分

一般将@interface部分放入.h文件中

 

Objective-c代码  
  1. #import <Cocoa/Cocoa.h>  
  2. @interface Tire:NSObject  
  3. @end  

 

将其他部分放在.m中,在.m中记得引入该头文件

#import "Tire.h"

import下<>代表系统头文件 ""代表本地头文件

关键词@class 告诉编译器此处是一个类,还需要通过指针进行传递

Objective-c代码  
  1. @class Tire  
  2. @class Engine  
  3. ...  
  4. Engine *engine  

注意这只有在通过指针指向其他类的情况下可用,减少编译器负担,在继承的情况下不可用,因为他需要了解超类的信息



----------------------------------------------

Foundation Kit

Cocoa由两个不同的框架组成 Foundation Kit和Application Kit

Foundation框架中有很多诸如NSString,NSArray等低级类和数据类型

 

 

Objective-c代码  
  1. #import <Foundation/Foundation.h>  
  2. int main(int argc, const char *argv[]){  
  3.     NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];  
  4.     //insert code here...  
  5.     NSLog(@"Hello, World!");  
  6.       
  7.     [pool drain];  
  8.     return 0;  
  9. }  

 

通过alloc创建并通过init初始化了一个池,在结尾处排空,这是Cocoa内存管理的预览

 

一些有用的数据类型

 

范围 NSRange

 

Objective-c代码  
  1. typedef struct _NSRange{  
  2.     unsigned int location;  
  3.     unsigned int length;  
  4. }NSRange;  

 

表示相关事物的范围,如字符串中的字符范围或数组中的元素范围

创建一个新的NSRange有3种方式

 

Objective-c代码  
  1. //1  
  2. NSRange range;  
  3. range.location=17;  
  4. range.length=4;  
  5. //2  
  6. NSRange range={17,4};  
  7. //3  
  8. NSRange range=NSMakeRange(17,4);  

 

第三种方法的好处是可以在任何能够使用函数的地方使用,比如当作参数

 

Objective-c代码  
  1. [anObject flarbulateWithRange: NSMakeRange(13,15)];  

 

 

几何数据类型 NSPoint,NSSize

 

Objective-c代码  
  1. typedef struct _NSPoint{  
  2.     float x;  
  3.     float y;  
  4. }NSPoint;  
  5.   
  6. typedef struct _NSSize{  
  7.     float width;  
  8.     float height;  
  9. }NSSize;  

 

比如Cocoa提供了矩形数据类型

 

Objective-c代码  
  1. typedef struct _NSRect{  
  2.     NSPoint origin;  
  3.     NSSize size;  
  4. }NSRect;  

 

同样提供了NSMakePoint(),NSMakeSize(),NSMakeRect()方法

将这些数据类型作为struct而不是对象的好处是性能更高

 

字符串 NSString

创建字符串

 

Objective-c代码  
  1. NSString *height;  
  2. height=[NSString stringWithFormat: @"Your height is %d feet",5];  

 

类方法

我们所创建的大部分方法是实例方法 用前导减号 - 声明

如果方法用于实现常规功能,用前导加好 + 来声明类方法

就如NSString的stringWithFormat方法

 

Objective-c代码  
  1. + (id) stringWithFormat: (NSString *) format, ...;  

 

关于大小

 

Objective-c代码  
  1. - (unsigned int) length;  

 

使用方式

 

Objective-c代码  
  1. unsigned int length=[height length];  

 

该方法可以正确处理国际字符串

比较

 

Objective-c代码  
  1. isEqualToString  
  2. - (BOOL) isEqualToString: (NSString *) aString;  

 

使用方式

 

Objective-c代码  
  1. NSString *thing1=@"hello 5";  
  2. NSString *thing2;  
  3. thing2=[NSString stringWithFormat: @"hello %d",5];  
  4. if(thing1 isEqualToString: thing2]){  
  5.     NSLog(@"They are the same!");  
  6. }  

 

同样的compare方法

 

Objective-c代码  
  1. - (NSCompar isonResult) compare: (NSString *) string;  

 

返回一个NSComparisonResult枚举类型

Objective-c代码  
  1. type enum _NSComparisonResult{  
  2.     NSOrderedAscending=-1,  
  3.     NSOrderedSame,  
  4.     NSOrderedDescending  
  5. }NSComparisonResult;  

如果返回NSOrderedAscending 表示左侧小于右侧 其他类似

不区分大小写的比较

Objective-c代码  
  1. - (NSComparisonResult) compare: (NSString *) string  
  2.                         options: (unsigned) mask;  

options参数是一个掩码

NSCaseInsensitiveSearch 不区分大小写

NSLiteralSearch 完全比较,区分大小写

NSNumericSearch 比较字符个数而不是字符值 比如100应该排在99以后

Objective-c代码  
  1. if([thing1 compare: thing2  
  2.         options: NSCaseInsensitiveSearch | NSNumericSearch] == NSOrderedSame){  
  3.             NSLog(@"They match");  
  4.         }  

判断字符串内是否包含其他字符串

Objective-c代码  
  1. - (BOOL) hasPrefix: (NSString *) aString;  
  2. - (BOOL) hasSuffix: (NSString *) aString;  

分别检查以特定字符串开头和结尾

Objective-c代码  
  1. - (NSRange) rangeOfString: (NSString *) aString;  

返回匹配的位置,如果找不到 则range.start=NSNotFound

 

可变性

NSString是不可变的

NSMutableString是可变字符串

两者间比较类似Java中的String和StringBuffer

创建NSMutableString的方法

Objective-c代码  
  1. + (id) stringWithCapacity: (unsigned) capacity;  

该容量只是一个建议 

Objective-c代码  
  1. NSMutableString *string;  
  2. string = [NSMutableString stringWithCapacity: 42];  

可以使用一些方法操作该string

Objective-c代码  
  1. - (void) appendString: (NSString *) aString;  
  2. - (void) appendFormat: (NSString *) format, ...;  

使用起来非常方便 也很显而易见

Objective-c代码  
  1. NSMutableString *string;  
  2. string=[NSMutableString stringWithCapacity: 50];  
  3. [string appendString: @"Hello here"];  
  4. [string appendFormat: @"human %d!",39];  
  5. //得到最后结果Hello here human 39!  

类似的

删除字符串中的字符

Objective-c代码  
  1. - (void) deleteCharactersInRange: (NSRange) range;  

NSMutableString是NSString的子类,所以可以使用NSString的所有功能

因此同样可以使用stringWithFormat来创建NSMutableString

 

集合家族 NSArray NSDictionary等

NSArray可以放入任意类型的对象

两个限制

1 只能存储Objective-C对象,而不能是C基础类型int,float,enum,struct等

2 不能存储零值nil NULL值

可以通过类方法arrayWithObjects创建,以逗号分割对象列表,并最后以nil表示列表结束

Ojbective-c代码  
  1. NSArray *array;  
  2. array=[NSArray arrayWithObjects: @"one",@"two",@"three",nil];  

获得对象个数

Objective-c代码  
  1. - (unsigned) count;  

取得特定索引处对象

Objective-c代码  
  1. - (id) objectAtIndex: (unsigned int) index;  

例如遍历一个数组

Objective-c代码  
  1. int i;  
  2. for(i=0;i<[array count];i++){  
  3.     NSLog(@"index %d has %@",i,[array objectAtIndex: i]);  
  4. }  

字符串切分成数组

Objective-c代码  
  1. -componentsSeparatedByString  

数组合并成字符串

Objective-c代码  
  1. -componentsJoinedByString  

可变数组

NSArray是不可变的,类似的NSMutableArray可变

创建新的可变数组

Objective-c代码  
  1. + (id) arrayWithCapacity: (unsigned) numItems;  

数组末尾添加对象

Objective-c代码  
  1. - (void) addObject: (id) anObject;  

删除特定位置对象

Objective-c代码  
  1. - (void) removeObjectAtIndex: (unsigned) index;  

枚举 NSEnumerator

通过objectEnumerator向数组请求枚举器

Objective-c代码  
  1. - (NSEnumerator *) objectEnumerator;   

 这似乎类似于Java的迭代器Iterator

使用

Objective-c代码  
  1. NSEnumerator *enumerator;  
  2. enumerator=[array objectEnumerator];  

可以从后向前浏览集合 reverseObjectEnumerator

请求下一个对象

Objective-c代码  
  1. - (id) nextObject;  

返回nil时表示结束

快速枚举

Objective-c代码  
  1. for(NSString *string in array){  
  2.     NSLog(@"I found %@",string);  
  3. }  
 

NSDictionary 有些类似于Map(散列表,关联数组)

类似的NSDictionary不可变,可变的NSMutableDictionary

创建字典的方法

Objective-c代码  
  1. + (id) dictionaryWithObjectsAndKeys: (id) firstObject, ...;  

例如

Objective-c代码  
  1. Tire *t1=[Tire new];  
  2. Tire *t2=[Tire new];  
  3. Tire *t3=[Tire new];  
  4. Tire *t4=[Tire new];  
  5.   
  6. NSDictionary *tires;  
  7.   
  8. tires=[NSDictionary dictionaryWithObjectsAndKeys: t1, @"front=left", t2, @"front-right", t3, @"back-left", t4, @"back-right", nil];  

使用objectForKey来获取值

Objective-c代码  
  1. - (id) objectForKey: (id) aKey;  

例如查找右后轮胎

Objective-c代码  
  1. Tire *tire=[tires objectForKey: @"back-right"];  

同样的,对于可变的字典

Objective-c代码  
  1. + (id) dictionaryWithCapacity: (unsigned int) numItems;  

为可变字典添加元素

Objective-c代码  
  1. - (void) setObject: (id) anObject forKey: (id) aKey;  

如果当前已有值,则新值会替代原有的值

删除

Objective-c代码  
  1. - (void) removeObjectForKey: (id) aKey;  

使用但不扩展

不要自己去创建NSString,NSArray,NSDictionary的子类

 

各种数值

就和Java中对int,float等有Integer,Float等对象封装,Objectvie-C也提供了NSNumber的包装类

Objective-c代码  
  1. + (NSNumber *) numberWithChar: (char) value;  
  2. + (NSNumber *) numberWithInt: (int) value;  
  3. + (NSNumber *) numberWithFloat: (float) value;  
  4. + (NSNumber *) numberWithBool: (BOOL) value;  

类似的还有long,long long等

例如将一个包装后的数据放入数组

Objective-c代码  
  1. NSNumber *number;  
  2. number=[NSNumber numberWithInt: 42];  
  3. [array addObject: number];  
  4. [dictionary setObject: num forKey: @"Bork"];  

从包装类获取值

Objective-c代码  
  1. - (char) charValue;  
  2. - (int) intValue;  
  3. - (NSString *) stringValue;  

 等

 

NSValue

NSNumber是NSValue的子类,NSValue可以包装任意值

Objective-c代码  
  1. + (NSValue *) valuseWithBytes: (const void *) value  
  2.     objCType: (const char *) type;  

例如,将NSRect放入NSArray

Objective-c代码  
  1. NSRect rect=NSMakeRect(1,2,3,4);  
  2.   
  3. NSValue *value;  
  4. value=[NSValue valueWithBytes: &rect  
  5.     objCType: @encode(NSRect)];  
  6. [array addObject: value];  

这里使用@encode编译器指令,它可以接受数据类型的名称并转化为合适的字符串

使用getValue取值

Objective-c代码  
  1. - (void) getValue: (void *) value;  

传递的是存储该数值的变量地址

Objective-c代码  
  1. value=[array objectAtIndex: 0];  
  2. [value getValue: &rect];  

Cocoa提供了常用的将struct型数据转换成NSValue的方法

Objective-c代码  
  1. + (NSValue *) valueWithPoint: (NSPoint) point;  
  2. + (NSValue *) valueWithSize: (NSSize) size;  
  3. + (NSValue *) valueWithRect: (NSRect) rect;  
 

Objective-c代码  
  1. - (NSPoint) pointValue;  
  2. - (NSSize) sizeValue;  
  3. - (NSRect) rectValue;  

例如,在NSArray中存储和检索NSRect

Objective-c代码  
  1. value=[NSValue valueWithRect: rect];  
  2. [array addObject: value];  
  3. ...  
  4. NSRect anotherRect=[value rectValue];  
 

NSNull

之前提到nil在NSArray和NSDictionary中有特殊的含义,所以不能把nil放入其中,如果要真的表示没有,Objectvie-C提供了NSNull

使用[NSNull null]==来比较是否为空



--------------------------------------------------------


完全是按照书上章节的顺序来的 这次是第九章的内容 关于内存管理

作为一名一直写java,当初就是因为java的自动垃圾回收机制,于是偷懒投奔java阵营的来说,这次不得不又回过头来面对这个问题了。后面的笔记只是对书中一些内容的记录总结,由于没有实战,具体使用中会碰到什么问题还是不得而知,而且我想那一定会存在相当多的问题,好在最后给出的三条准则还是非常易用的。(听同伴说xCode提供了检查内存泄露的工具,挺好用)

本章最后提到了Objective-C也同样可以打开垃圾回收,不过由于只对高版本有效,并非通用,所以个人感觉既然使用了Objective-C,因此还是应该掌握内存管理的方法。

 

对象的声明周期:

诞生(通过alloc或new)、实现(接收消息和执行操作)、交友(借助方法的组合和参数)、死去(被释放)

Cocoa使用引用计数

当使用alloc,new或者copy方法创建一个对象时,计数器值设为1

发送retain消息增加计数器值,减少使用release

当计数器归0,Objective-C自动发送dealloc消息,可以重写dealloc方法,但是不要直接去调用该方法

发送retainCount消息获得当前计数器值

 

Objective-c代码  
  1. - (id) retain;  
  2. - (void) release;  
  3. - (unsigned) retainCount;  
 

 

Objective-c代码  
  1. [[car retain] setTire:tire at Index:2];  

表示要求car对象将计数器加1,并执行setTire操作

 

一种set方法的正确内存管理方法

 

Objective-c代码  
  1. - (void) setEngine: (Engine *) newEngine{  
  2.     [newEngine retain];   
  3.     [engine release];  
  4.     engine=newEngine;  
  5. }  
 

自动释放池

NSObject类提供了autorelease方法

 

Objective-c代码  
  1. - (id) autorelease;  

执行后对象将被添加到自动释放池中,自动释放池被销毁时,向其中所有对象发送release消息

 

Cocoa内存管理规则

* 当使用new,alloc,copy方法创建一个对象时,该对象保留计数器为1,如果不再使用该对象,需要手动发送release或autorelease消息

* 通过其他方式获得的对象,则假设该对象计数器为1,并以设置自动释放,不需要做任何事,如果需要在一段时间内使用,那么保留该对象并确保在工作完成后释放

* 如果保留了某个对象,最终需要手动释放该对象,保持retain和release使用次数相等

 

例如

临时对象

 

Objective-c代码  
  1. NSMutableArray *array;  
  2. array=[[NSMutableArray alloc] init];  
  3. //...use array...  
  4. [array release];  

使用了alloc获得对象,所以用完需要释放

 

 

Objective-c代码  
  1. NSMutableArray *array;  
  2. array=[NSMutableArray arrayWithCapacity:17];  
  3. //use it, autorelease  

注意这里使用了arrayWithCapacity获得对象,并不是3者之一,所以无需做任何事

 

 

Objective-c代码  
  1. NSColor *color;  
  2. color=[NSColor blueColor];  

和上述情况相同,其实这里的blueColor是一个全局单例对象,永远不会被销毁

 

拥有对象

 

Objective-c代码  
  1. - (void) doStuff{  
  2.     //flonkArray is an instance variable  
  3.     flonkArray=[NSMutableArray new];  
  4. }  
  5. - (void) dealloc{  
  6.     [flonkArray release];  
  7.     [super dealloc];  
  8. }  
 

 

 

Objective-c代码  
  1. - (void) doStuff{  
  2.     //flonkArray is an instance variable  
  3.     flonkArray=[NSMutableArray arrayWithCapacity: 17];  
  4.     [flonkArray retain];  
  5. }  
  6. - (void) dealloc{  
  7.     [flonkArray release];  
  8.     [super dealloc];  
  9. }  

相关文章

    暂无相关文章

用户评论