Objective-C 对比学习

在我们学习一门新的语言时,总要把它和我们熟悉的语言对比着来学习,就象学习英语时,都要记单词的汉语意思,来帮助我们对单词的理解和记忆。

下面通过与C#的对比来学习Objective-C, 首先对比一下语言的定义:

Objective-C,通常写作ObjC和较少用的Objective C或Obj-C,是在C的基础上,加入面向对象特性扩充而成的编程语言。

目前,Objective-C主要应用于Mac OS X和iOS这两个NeXTSTEP的派生系统,而在NeXTSTEP和OpenStep中它更是基本语言。Objective-C可以在任何gcc支持的平台上进行编译,因为gcc本地支持Objective-C。

C#是微软推出的一种基于.NET框架的、面向对象的高级编程语言。C#由C语言和C++派生而来,继承了其强大的性能,同时又以.NET 框架类库作为基础,拥有类似Visual Basic的快速开发能力。

Objective-C是在C的基础上加入了面向对象的特性,而C#是由C和C++派生而来,可见C#显得更“高级”一些.

1. Objective-C is a strict superset of C

2. Single inheritance

3. Protocols define behavior that cross classes

4. Dynamic runtime

5. Loosely typed

1. C#是全新设计的,没有什么superset。

2. 单继承。

3. 感觉就象C#的interface.

4. 应该是相对C语言来说的,不同于link的方式,ObjC使用了基于消息传递(message-passing)的方式进行方法调用。

5. C#中的用object定义和传递变量应该算上Loosely。

Message Expression

[reciever message]
[reciever message:argument]
[reciever message:argument andArg:arg2]

Metho definition
- (void)castBallot;
- (int)arg;
- (void)setArg:(int)age;
- (void)registerForState:(NSString*)state party:(NSString*)party;

对于C#开发人员,这样的代码看起来很诡异,别紧张,把它想象成方法调用就对了。

Objective-C 2.0 introduced dot syntax

float height = [persion height];
float height = persion.height;

[persion setHeight:newHeight];
persion.height = newHeight;

[[persion child] setHeight:newHeight];
persion.child.height = newHeight;

也许是为了ObjC看上去不那么“诡异”,终于看上去“正常”了一些吧~!

id anObject;
Persion  *aPersion = (Persion *)anObject;

这是所谓的“Loosely typed”吧,id应该是一个指象对象的指针吧。

nil

if(persion == nil) return;
if(!persion) return;

persion = nil;
[button setTarget: nil];

persion = nil;
[persion castBallot];

nil就是C#里的null,不同的是OjbC中nil上调用方法不出错,对照mesage-passing方式,就好理解了,不就是没人接收消息嘛,那就什么也不做好了。

When ObjC was developed, C has no boolean type (C99 introduced one).

ObjC uses a typedef to define BOOL as a type

BOOL flag = NO;

OjbC没有bool类型,通常使用YES和NO,也可以使用TRUE和FALSE,或者干脆使用0和1表示。

SEL

SEL action = [button action];
[button setAction:@selector(start:)];

Conceptually similar to function pointer
- (void)setName:(NSString*)name age:(int)age;
SEL sel = @selector(setName:age:);

感觉很象C#中的委托(delegate).

Class:

Class myClass = [myObject class];
NSLog(@"My class is %@", [myObject className]);

if ([myObject isKindOfClass:[UIControl class]])
{
 // something
}


if ([myObject isMemberOfClass:[NSString class]])
{
 // someting string specific
}

C#中有Type, 上面的代码在C#中如下:

Type myClass = myObject.GetType();
Console.WriteLine(string.Format("My class is {0}", myClass.TypeName));
if(myObject.GetType() == typeof(UIControl))
{
  // something
}

if (myObject is typeof(String))
{
 // someting string specific
}

Identity versus Equality

Identity - testing equality of the pointer values

if (object1 == ojbect2)
{
  NSLog(@"Same exact object instance");
}

Equality - testing object attributes

if ([object1 isEqual: object2])
{
  NSLog(@"Logically equivalent, but may be different object instances");
}

C#中好象没有直接比较对象属性值的功能,得自已override Equals方法。

description:

- (NSString*)description;

[NSString stringWithFormat: @"The answer is: %@", myObject];

NSLog([anObject description]);
这不就是object的ToString()方法吗?!

NSObject

对等于C#中的Object类。

NSString

In C constant strings are

"simple"

In ObjC constant strings are

@"just as simple"

NSString *aString = @"Hello World!";

NSLog(@"I am a %@, I have %d items", [array className], [array count]);

NSString *myString = @"Hello";
NSString *fullString;
fullString = [myString stringByAppendString:@" world!"];

fullString would be set to "Hello World!".

- (BOOL) isEqualToString:(NSStirng*)string;
- (BOOL) hasPrefix:(NSString*)string;
- (int)intValue;
- (double)doubleValue;

基本上没什么好说的,这就是System.Stirng.

Common NSMutableString methods:

+ (id)string;
- (void)appendString:(NSString*)string;
- (void)appendFormat:(NSString*)format, ...;
示例:
NSMutableString *newString = [NSMutableString string];
[newString appendString:@"Hi"];
[newString appendFormat:@" , my favorite number is: %d", [self favoriteNumber]];

是不是很象StringBuilder?

Collections

Array, Dictionary, Set

Common NSArray methods:

+ arrayWithObjects:(id)firstObj, ...; //nil terminated!!!
- (unsigned)count;
- (id)objectAtIndex:(unsigned)index;
- (unsigned)indexOfObject:(id)object;

NSNotFound returned for index if not found

if ([array indexOfObject:@"Purple"] == NSNotFound)
{
  NSLog(@"No color purple");
}

NSNotFound不就是-1吗?!

NSMutableArray

NSMutalbeArray subclasses NSArray.

Common NSDictionary methods:

+ dictionaryWithObjectsAndKeys:(id)firstObject, ...;
- (unsigned)count;
- (id)objectForKey:(id)key;

nil returned if no object found for gived key.

NSMutalbeDictionary

NSMutalbeDictionary subclasses NSDictionary.

Common NSSet methods:

+ setWithOjbects:(id)firstObj, ...; //nil terminated
- (unsigned)count;
- (BOOL)containsObject:(id)object;

No object is ever in there more than once.

NSMutableSet

NSMutableSet subclasses NSSet

C#好象没Set这样的东东,怎么没什么印象呢?!不过看样子搞一个也不是很麻烦。

Enumeration

for (Persion *persion in array)
{   
  NSLog([persion description]);
}

C#的foreach就对了。

Common NSNumber methods:

+ (NSNumber*)numberWithInt:(int)value;
+ (NSNumber*)numberWithDouble:(double)value;
- (int)intValue;
- (double)doubleValue;

NSData/NSMutableData

NSDate/NSMutableDate

byte[] 和 DateTime就对了。

Class interface declared in header file

#import <Foundation/Foundation.h>

@interface Persion : NSObject
{
  // instance variables
  NSString *name;
  int arg;   
}

// method declarations
- (NSString *)name;
- (void)setName:(NSString *)value;

- (int)age;
- (void)setAge:(int)age;

- (BOOL)canLegallyVote;
- (void)castBallot;
@end

Class Implementation write in .m file

#import "Persion.h"

@implemetation Person

- (int)age
{
  return age;
}


- (void)setAge:(int)value
{
  age = value;
}


// ... and other methods


- (BOOL)canLegallyVote
{
  return ([self age] >= 18);
}


- (void)castBallot
{
  if([self canLegallyVote])
  {
    // do voting stuff
  }
  else
  {
    NSLog(@"I'm not allowed to vote!");
  }
}

@end

还是感觉一个类一个文件简洁。

SuperClass methods

- (void)doSomething
{
  // Call superclass implementation first
  [super doSometing];

  // Then do our custom behavior
  int foo = bar;

  // ...
}

ObjC super 等于 C# base

Object Creation

+ alloc

Class method that knows how much memory is needed.

- init

Instance method to set initial values, perfomr other setup.

Create = Allocate + Initialize

Persion *persion = nil;
Persion *persion = [[Persion alloc] init];

不就是new个对象吗?!还搞成这样??!!!

Implementing your own - init method

#import "Persion.h"

@implementation Person

- (id)init
{
  // allow superclass to initialize its state first
  if (self == [super init])
  {
     age = 0;
     name = @"Bob";

     // do other initialization...
  }

   return self;
}

@end

Multiple init methods

- (id)init;
- (id)initWithName:(NSString *)name;
- (id)initWithNameAndAge:(NSString *)name age:(int)age;

Less specific ones typically call more specific with default values

- (id)init
{
  return [self initWithName:@"No Name"];
}

- (id)initWithName:(NSString *)name
{
  return [self initWithNameAndAge:name age:0];
}
Persion *persion = [[Persion alloc] init];
// ...
[persion release]; // Object is deallocated

[persion doSomething]; // Crash!

persion = nil;
[persion doSomething]; // No effect

Implementing a -dealloc method

#import "Persion.h"

@implementation Persion

- (void)dealloc
{
  // Do any cleanup that's necessary
  // ...
  [name release];

  // when we're done, call super to clean us up
  [super dealloc];
}

@end

构造函数和析构函数。

Object Ownership

#import "Persion.h"

@implementation Persion

- (NSString *)name
{
  return name;
}

// retain
- (void)setName:(NSString *)newName
{
  if (name != newName)
 {
  [name release];
  name = [newName retain];
  // name's retain count has been bumped up by 1
 }
}

// copy
- (void)setName:(NSString *)newName
{
  if (name != newName)
 {
  [name release];
  name = [newName retain];
  // name's retain count has been bumped up by 1
 }
}

Returning a newly created object

- (NSString *)fullName
{
  NSString *result;
  result = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
  [result autorelease];
  return result;
}

Autorelease is not garbage collection, Objective-C on iPhone OS does not have garbage collection.

C#的GC,优势尽显,这也表现出来的“高级”的地方吧!

Defining Properites

@property int age;
@property (copy) NSString *name;
@property (readonly) BOOL canLegallyVote;

Synthesizing Properties

- (int)age
{
  return age;
}

- (void)setAge:(int)value
{
  age = value;
}

- (NSString *)name
{
  return name;
}

- (void)setName:(NSString *)value
{
  if(value != name)
  {
     [name release];
     name = [value copy];
  }
}
@implementation Person

@synthesize age;
@synthesize name;
- (BOOL)canLegallyVote
{
 return (age > 17);
}

Memory namagement policies

@property (assign) NSString *name; // pointer assignment
@property (retain) NSString *name; // retain called
@property (copy) NSString *name; // copy called

Property Names vs. Instance Variables

@interface Persion : NSObject
{
  int numberOfYearsOld;
}

@property int age;

@end
@implemetation Persion

@synthesize age = numberOfYearsOld;

@end

就是property没什么说的。

Method type identifier

类方法:+

实例方法: -

ObjC 的+ 等于 C#中的static, 不过ObjC中没有public和 private。

参考学习资料:

http://v.163.com/special/opencourse/iphonekaifa.html

http://rotator.youkulabs.com/?f5527199o1p0