1 變量聲明
變量的聲明與C語言一樣,在變量名前加類型名
以下這些數據類型是從C語言中直接拿來使用的:
int n; unsigned int n; char n; unsigned char n; long n; float n; double n;
另外,Objective-C還擴展了一些數據類型,布爾類型用YES和NO來表示邏輯1和邏輯0
BOOL isOK = YES; BOOL isBAD = NO;
Objective-C中的對象聲明就是該對象的指針聲明
NSString *string; NSArray * array; NSDictionary* dictinary;
2 類的聲明和實現的區別
類的聲明一般寫在.h文件中,而實現則寫在.m文件中。.h文件又稱為接口文件,它只會規定一個類有哪些成員變量和成員函數,而不去具體實現它。這個.h文件一般由架構師來撰寫。.m文件中具體實現類的成員函數,它往往由軟件工程師負責。
3 新建對象和釋放內存
生成一個對象,有兩種方法:alloc+init系列和autorelease釋放。
因為沒有垃圾回收機制,Objective-C采用計數器的方式來管理內存,使用的時候要特別小心。
用retain方法對計數器加1,用release方法對計數器減1
3.1 alloc函數+init系列函數
初始化時,用alloc函數+init系列函數方法時,計數器的狀態會被設為1,使用完畢后,務必記得要用release方法來釋放內存。
NSArray *array = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", nil]; // 對array的一些處理 [array release]; // 釋放array的內存
用alloc函數+init系列函數的方法生成的對象也可以委托autorelease來釋放。
NSArray *array = [[[NSArray alloc] initWithObjects:@"a", @"b", @"c", nil] autorelease];
3.2 autorelease釋放
使用autorelease時,初始化對象的計數器值也被設為1。當達到autorelease的scope的時候,該對象就會收到一個release消息,這就實現了內存自動釋放。
NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];
3.3 數值
int i = 2 int i = 100000000; float radius = 1.0f; double diameter = 2 * M_PI * radius;
3.4 四則運算
num = 1 + 1; num = 1 - 1; num = 1 * 2; num = 1 / 2;
求商的方法是這樣的,如果被除數與除數都是整數,則計算結果是向下取整的整數(小數點后面的全部去掉)。
num = 1 / 2; // 0
如果被除數與除數中有一個是小數,則計算結果不舍棄小數部分。
num = 1.0 / 2; // 0.5 num = 1 / 2.0; // 0.5 num = 1.0 / 2.0; // 0.5
下面是求余:
// 求余
mod = 4 % 2;
3.5 自增和自減
// 自增 num++; ++num; // 自減 num--; --num;
同C語言中的自增和自減運算一樣,如果單獨使用則運算符放在左邊和右邊都一樣,當在代數式和條件式中使用時,則要特別小心。請不清楚的讀者網上搜索一下C語言的自增和自減的注意點。
4 字符串
4.1 字符串的表示
字符串使用NSString,用@”"來表示字符串。
NSString是只讀的字符串。
NSString *string = @"Hello World!";
可修改的字符串要這樣聲明:
NSMutableString * string = [NSMutableString stringWithString:@"Hello World!"];
4.2 字符串操作
// 與字符串連接
NSMutableString * string = [NSMutableString stringWithString:@"aaa"];
NSString *joined = [string appendString:@"bbb"];
//字符串追加
NSMutableString *str=[[NSMutableStringalloc] initWithString:@"dd"];
str=[str stringByAppendingString:@"eee" ];
//字符串替換
NSString *str = @"Hello world!";
str =[str stringByReplacingOccurrencesOfString:"world" withString:"China"];
NSlog(@"Your String is = %@",str);
你將會看到輸入Hello China
// 與數組連接
NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; NSString *joined = [array componentsJoinedByString:@","];
//分割數組
NSString * string = [NSMutableString stringWithString:@"aaa,bbb,ccc"];
NSArray *record = [string componentsSeparatedByString:@","];
// 字符串長度 int length = [@"abcdef" length];
//提取字串
NSString *string = [@"abcd" substringWithRange:NSMakeRange(0, 2)]; // ab
//搜索
NSString *string = @"abcd"; NSRange range = [string rangeOfString:@"cd"];
NSLog(@"%d:%d", range.location, range.length); //如果沒有找到,則length = 0
//字符串轉換為日期
NSDate *date1=[dateFormatter dateFromString:@"2010-3-3 11:00"];
//日期比較
首先,創建一個日期格式化對象:
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];
然后,創建了兩個日期對象:
NSDate *date1=[dateFormatter dateFromString:@"2010-3-3 11:00"];
NSDate *date2=[dateFormatter dateFromString:@"2010-3-4 12:00"];
創建日期對象,是通過字符串解析的。
然后取兩個日期對象的時間間隔:
NSTimeInterval time=[date2 timeIntervalSinceDate:date1];
這里的NSTimeInterval 並不是對象,是基本型,其實是double類型,是由c定義的:
typedef double NSTimeInterval;
再然后,把間隔的秒數折算成天數和小時數:
int days=((int)time)/(3600*24);
int hours=((int)time)%(3600*24)/3600;
NSString *dateContent=[[NSString alloc] initWithFormat:@"%i天%i小時",days,hours];
字符串轉換為整數
1 |
NSString *aNumberString = @"123"; |
2 |
int i = [aNumberString intValue]; |
dobule di = [aNumberString doubleValue]; //轉換為雙精度
整數轉換為字符串
1 |
int aNumber = 123; |
2 |
NSString *aString = [NSString stringWithFormat:@"%d", aNumber]; |
5 數組
5.1 聲明
NSArray *array;
5.2 數組的生成
NSArray *array; array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; NSMutableArray *array = [NSMutableArray array]; // 聲明可修改的數組同時對它賦值
5.3 數組元素的引用和賦值
// 元素的引用 [array objectAtIndex:0]; [array objectAtIndex:1]; // 賦值(NSMutableArray的實例) [array removeObjectAtIndex:1]; // 刪除一個元素 [array insertObject:@"1" atIndex:1]; // 在刪除的地方插入一個元素
5.4 數組的長度
int array_num = [array count];
6 字典
6.1 聲明
NSDictionary *dictinary; dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"value1",@"key1", @"value2",@"key2", nil, ]; NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; // 聲明可修改的字典的同時對它賦值
6.2 字典元素的引用和賦值
//元素的引用 id val1 = [dictionary objectForKey:@"key1"]; id val2 = [dictionary objectForKey:@"key2"]; // 賦值(NSMutableDictionary的實例) [dictionary setObject:@"value1" forKey:@"key1"];
6.3 字典的操作
・獲得Key
NSArray *keys = [dictionary allkeys]
・獲得值
NSArray *values = [dictionary allValues];
・刪除Key(NSMutableDictionary的實例)
[dictionary removeObjectForKey:@"key1"];
7 控制語句
if語句
if ( 條件 ) {
}
if ~ else語句
if (條件) {
} else {
}
if ~ else if 語句
if ( 條件 ) {
} else if ( 條件 ) {
}
while語句
int i = 0;
while (i < 5) {
// 處理
i++;
}
for語句
for (int i = 0; i < 5; i++) {
//處理
}
8 函數定義
雖然大多數情況下是用類中的方法來定義函數,但也可以用C語言的函數定義方法。
另外,還有作為對現有類的擴張的方法,稱之為Category。
@interface ClassA : NSObject { NSString *name_; } @property (nonatomic, copy) NSString *name_; @implementation ClassA @synthesize name_ - (void) helloWorld:(NSString *)name { NSLog(@"hello %@ world! from %@", name, self.name_); } @end
9 文件的輸入輸出
NSString *inputFilePath = [INPUTFILEPATH stringByExpandingTildeInPath]; NSString *outputFilePath = [OUTPUTFILEPATH stringByExpandingTildeInPath]; NSFileManager *fm = [NSFileManager defaultManager]; if ( ![fm fileExistsAtPath:outputFilePath] ) { [fm createFileAtPath:outputFilePath contents:nil attributes:nil]; } NSFileHandle *input = [NSFileHandle fileHandleForReadingAtPath:inputFilePath]; NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:outputFilePath]; @try { NSData *data; while( (data = [input readDataOfLength:1024]) && 0 < [data length] ){ [output writeData: data]; } } @finally { [input closeFile]; [output closeFile]; }
以下語法特性,讀者如果知道的話會更好:
高速枚舉
使用NSArray或NSDictionar的高速枚舉法可以簡單地枚舉元素
NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];
for (id i in array) {
//一些處理
}
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", @"value3", @"key3", nil ]; // 用key來做循環的場合 for (id i in [dictionary keyEnumerator]) { // 一些處理 } // 用值來做循環的場合 for (id i in [dictionary objectEnumerator]) { // 一些處理 }
用臨時變量id來做是可以的,不過指明Key的類型這種方法也不錯。
for (NSString *k in [dictionary keyEnumerator]) {
// 處理
}
Category
Category可以在已有的類中追加一個方法
@interface NSString (Decorate) // 定義屬於Category的方法 - (NSString *) decorateWithString:(NSString *)string; @end @implementation NSString (Decorate) - (NSString *) decorateWithString:(NSString *)string { return [NSString stringWithFormat:@"%@%@%@", string, self, string]; } @end NSLog(@"test: %@",[@"[MSG]" decorateWithString:@"**"]); // **[MSG]**
Protocol
類如果聲明為符合某種Protocol的話,就要按照Protocol所規定的方法來實現這個類。Protocol和Java中的Interface類似。
Property
Property提供了訪問類中成員變量的一種方法。
雖然在使用的時候你應該知道更多關於它的知識,但在這里我們只舉一個例子。
@property (nonatomic, retain) NSArray *array_;
如果要對像上面那樣聲明retain的property賦值的話,如果不通過accessor來訪問,那么就無法retain。
- (id)initWithParam:(NSArray *)array {
if (self = [super init]) {
array_ = array; // 無法retain
self.array_ = array; // 可以retain
}
return self;
}
- (void)dealloc {
[array_ release];
[super dealloc];
}
由於該狀態並不是retain,外部進程可能會對其進行釋放,這樣就會出現EXC_BAD_ACCESS或者double free的錯誤發生。
