在我們學習一門新的語言時,總要把它和我們熟悉的語言對比著來學習,就象學習英語時,都要記單詞的漢語意思,來協助我們對單詞的理解和記憶。
下面通過與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