雖然現(xiàn)在身處大公司,但是因?yàn)槭莾?nèi)部創(chuàng)業(yè)團(tuán)隊(duì),產(chǎn)品、native、前端、服務(wù)器端全部坐在一起開(kāi)發(fā),大家很容易做零距離交流,也因?yàn)樽罱鼉?nèi)部有一個(gè)前端要轉(zhuǎn)崗過(guò)來(lái),于是手里的前端任務(wù)好像可以拋一大坨出去了,這個(gè)時(shí)候立刻想到了切入IOS開(kāi)發(fā)?。?!
事實(shí)上,前端開(kāi)發(fā)做到一定時(shí)間,要進(jìn)步很難了,最近幾個(gè)月?lián)涞綐I(yè)務(wù)上便感覺(jué)突破不了目前的瓶頸,自身的前端瓶頸主要在兩方面:技術(shù)深度、技術(shù)廣度
其實(shí)不論深度或者廣度來(lái)說(shuō)都不是簡(jiǎn)單前端能說(shuō)清楚的事情,不能說(shuō)了解了angularJS、react等框架技術(shù)深度就深了,因?yàn)槭聦?shí)上angular中包含了很多設(shè)計(jì)思想,學(xué)習(xí)他是編程思想的提升,并不單是js功力的提升。
要說(shuō)自身職業(yè)規(guī)劃,前端當(dāng)然可以往nodeJS發(fā)展走大前端方向,但是這個(gè)真的需要項(xiàng)目支持,多次嘗試自學(xué)nodeJS皆收效甚微,便是因?yàn)闆](méi)有實(shí)際項(xiàng)目支持,說(shuō)白了沒(méi)有人帶著做項(xiàng)目。
而團(tuán)隊(duì)內(nèi)部有人帶著做IOS開(kāi)發(fā),我居然可以從零開(kāi)始自學(xué)然后參與生產(chǎn)項(xiàng)目開(kāi)發(fā),想想真的令人興奮?。?!
但是天下沒(méi)有不要錢(qián)的午餐,切入IOS開(kāi)發(fā)的前提是保證現(xiàn)有H5任務(wù)的工期以及質(zhì)量,所以加班什么的在所難免,可是我怎么可能放棄這種千載難逢的好事呢?于是立馬給技術(shù)老大說(shuō)了愿意多承擔(dān)工作的意愿,老大也很nice的答應(yīng)我可以切入IOS開(kāi)發(fā),于是這一切便如此美好的開(kāi)始了!所以接下來(lái)一段時(shí)間只需要fighting就夠了?。?!
感謝慕課網(wǎng)的入門(mén)教程,同樣感謝網(wǎng)上諸多資料,特別是該園友博客:http://www.survivalescaperooms.com/kenshincui/
今時(shí)不同往日,已經(jīng)不可能有太多的空閑時(shí)間給我學(xué)習(xí)了,剛開(kāi)始也想過(guò)應(yīng)該系統(tǒng)的學(xué)習(xí),一章一章的鞏固知識(shí),但是這樣效率太低,等我學(xué)完都猴年馬月了,項(xiàng)目早結(jié)束了
所以現(xiàn)在適合我的學(xué)習(xí)方法是做簡(jiǎn)單并且熟悉多項(xiàng)目,比如大一的C語(yǔ)言考試,學(xué)生管理系統(tǒng)
簡(jiǎn)單設(shè)計(jì)一個(gè)學(xué)生管理系統(tǒng),要求具有以下功能:
1 可以錄入學(xué)生姓名,性別、課程等信息
2 可以給各門(mén)課程錄入考試成績(jī)
3 支持姓名排序,班級(jí)排序,成績(jī)排序
因?yàn)樽畛踝鲰?xiàng)目是為了熟悉語(yǔ)言,所以不需要太復(fù)雜,于是我們便開(kāi)始吧!?。?/p>
你要開(kāi)發(fā)IOS程序,首先得有一臺(tái)Mac機(jī),其次需要安裝xcode開(kāi)發(fā)工具,我反正是去借了一臺(tái),然后讓同事考了一個(gè)最新版的xcode,于是開(kāi)始開(kāi)發(fā)吧。
OC中的類皆繼承至NSObject類,會(huì)帶有一些特有并且經(jīng)常會(huì)用到的方法,具體細(xì)節(jié)我們不去糾結(jié),直接創(chuàng)建類吧
新建一個(gè)類會(huì)形成兩個(gè)文件:file.h頭文件與file.m為類的具體實(shí)現(xiàn)文件,我們這里新建一個(gè)Student類:
1 #import <Foundation/Foundation.h>2 3 @interface Student : NSObject4 5 @end#import "Student.h"@implementation Student@end我們這里不去吐槽OC的怪異語(yǔ)法,因?yàn)槲覀內(nèi)绻萌W(xué)習(xí)一個(gè)東西,就不要吐槽他,這樣會(huì)分散你的注意力并且會(huì)讓學(xué)習(xí)難以繼續(xù),所以回到正題
OC的屬性定義在頭文件中,以學(xué)生來(lái)說(shuō)我們規(guī)定其有以下屬性,其中課程真實(shí)場(chǎng)景會(huì)被抽象為一個(gè)類,所以我們也這樣做吧,新建Course類,并且給學(xué)生的屬性如下:
1 #import <Foundation/Foundation.h> 2 #import "Course.h" 3 4 @interface Student : NSObject 5 { 6 NSString *_name; 7 int _age; 8 NSString *_sex; 9 Course *_chinese;10 Course *_math;11 //錄入時(shí)間12 NSDate *_dateCreate;13 }14 @end課程類只具有名字與得分兩個(gè)屬性:
1 #import <Foundation/Foundation.h>2 3 @interface Course : NSObject4 {5 NSString *_name;6 float _score;7 }8 @end其中下劃線定寫(xiě)法為OC的規(guī)則,我們不需要知道他為什么要這樣做,先做再說(shuō),后面熟悉了自然就知道了,與C#一樣,屬性會(huì)有g(shù)etter與setter方法,OC這里提供了語(yǔ)法糖,我們暫不使用,老老實(shí)實(shí)的寫(xiě)代碼,下面為兩個(gè)類的具體實(shí)現(xiàn):
Student-Course構(gòu)造函數(shù)是每個(gè)類實(shí)例化的入口點(diǎn),每一個(gè)繼承至NSObject的對(duì)象都會(huì)有一個(gè)init的實(shí)例方法,這個(gè)便是其構(gòu)造函數(shù),我們這里自定義構(gòu)造函數(shù),Course與Student的構(gòu)造函數(shù)
View Code 1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3 #import "Course.h" 4 5 int main(int argc, const char * argv[]) { 6 @autoreleasepool { 7 8 //alloc方法創(chuàng)建實(shí)例空間,init初始化 9 Course *c = [[Course alloc] initWithName:@"葉小釵" andScore:90];10 11 NSLog(@"%@, %f", c.name, c.score);12 13 }14 return 0;15 }成功打印出我們想要的代碼,所以這個(gè)時(shí)候再將Student類的構(gòu)造方法加上,并且給Student釋放一個(gè)對(duì)外實(shí)例方法:showData
View Code 1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3 #import "Course.h" 4 5 int main(int argc, const char * argv[]) { 6 @autoreleasepool { 7 8 //alloc方法創(chuàng)建實(shí)例空間,init初始化 9 Course *chinese = [[Course alloc] initWithName:@"語(yǔ)文" andScore:90];10 Course *math = [[Course alloc] initWithName:@"數(shù)學(xué)" andScore:95];11 12 Student *s = [[Student alloc] initWithName:@"葉小釵" andAge:27 andSex:@"男" andChinese:chinese andMath:math];13 14 [s showData];15 16 }17 return 0;18 }2015-08-06 23:42:24.853 student[3394:246243] 姓名:葉小釵2015-08-06 23:42:24.854 student[3394:246243] 性別:男2015-08-06 23:42:24.854 student[3394:246243] 年齡:272015-08-06 23:42:24.855 student[3394:246243] 課程名:語(yǔ)文2015-08-06 23:42:24.855 student[3394:246243] 課程得分:90.0000002015-08-06 23:42:24.855 student[3394:246243] 課程名:數(shù)學(xué)2015-08-06 23:42:24.855 student[3394:246243] 課程得分:95.000000PRogram ended with exit code: 0顯然,學(xué)生不只一個(gè),我們需要一個(gè)集合來(lái)裝載所有的學(xué)生,對(duì)于沒(méi)有OC經(jīng)驗(yàn)的我第一時(shí)間想到了數(shù)組,所以我們首先來(lái)簡(jiǎn)單了解下OC中的數(shù)組
數(shù)組屬于集合大家族中的一類,簡(jiǎn)單來(lái)說(shuō)有數(shù)組和字典,NSArray NSDictionary
NSArray是一個(gè)Cocoa類,用來(lái)存儲(chǔ)對(duì)象的有序列表,我們可以在NSArray中放入任意類型的對(duì)象:字符串、對(duì)象,基本類型等。
NSArray有兩個(gè)限制,首先是只能存儲(chǔ)OC類型的對(duì)象,同時(shí)不要在里面存儲(chǔ)nil(對(duì)應(yīng)其它語(yǔ)言中的NULL),我們可以使用類方法arrayWithObjects創(chuàng)建一個(gè)數(shù)組對(duì)象,比如:
1 //nil代表數(shù)組結(jié)束 2 NSArray *array = [NSArray arrayWithObjects:@"葉小釵", 23, math, nil]; 3 4 //或者這樣,注意這里會(huì)報(bào)錯(cuò),因?yàn)镹SArray只能保存對(duì)象,但23卻是基本類型 5 //前面能處理是因?yàn)閮?nèi)部發(fā)生了裝箱拆箱的過(guò)程 6 //NSArray *array2 = @[@"葉小釵", 23, math]; 7 NSNumber *num1 = [[NSNumber alloc] initWithInt:23]; 8 NSArray *array2 = @[@"葉小釵", num1, math]; 9 10 NSLog(@"%d", array[1]);11 NSLog(@"%d", [array2[1] intValue]);
下面是數(shù)組的一些其它操作:
PS:這里插一根nslog相關(guān)的類型映射
1 %@ 對(duì)象 2 %d, %i 整數(shù) 3 %u 無(wú)符整形 4 %f 浮點(diǎn)/雙字 5 %x, %X 二進(jìn)制整數(shù) 6 %o 八進(jìn)制整數(shù) 7 %zu size_t 8 %p 指針 9 %e 浮點(diǎn)/雙字 (科學(xué)計(jì)算)10 %g 浮點(diǎn)/雙字11 %s C 字符串12 %.*s Pascal字符串13 %c 字符14 %C unichar15 %lld 64位長(zhǎng)整數(shù)(long long)16 %llu 無(wú)符64位長(zhǎng)整數(shù)17 %Lf 64位雙字
18 %i 布爾型
1 //nil代表數(shù)組結(jié)束 2 NSArray *array = [NSArray arrayWithObjects:@"葉小釵", @"111", @"ddd", @"dd11", nil]; 3 4 //數(shù)組遍歷 5 //array count求得數(shù)組長(zhǎng)度 6 for (int i = 0; i < [array count]; i++) { 7 NSLog(@"%@", array[i]); 8 } 9 10 //更好的遍歷方式11 for(id item in array){12 NSLog(@"%@", item);13 }14 15 //判斷是否包含某個(gè)對(duì)象=>116 NSLog(@"%i", [array containsObject:@"1111"]);17 //判斷是否包含某個(gè)對(duì)象=>018 NSLog(@"%i", [array containsObject:@"葉小釵"]);19 20 //返回第一個(gè)找到對(duì)象的索引=>221 NSLog(@"%d", [array indexOfObject:@"ddd"]);22 23 //簡(jiǎn)單排序語(yǔ)法糖,很實(shí)用,后面會(huì)使用這里不詳說(shuō)24 NSArray *array1 = [array sortedArrayUsingSelector:@selector(compare:)];25 26 for(id item in array1){27 NSLog(@"%@", item);28 }
這里排序后面會(huì)有更多的應(yīng)用
與NSSting一致,NSArray創(chuàng)建的是不可變數(shù)組,一旦創(chuàng)建包含特定數(shù)量的數(shù)組便不能再增減,為了彌補(bǔ)NSArray的不足,便有了NSMutabeArray類,通過(guò)arrayWithCapacity來(lái)創(chuàng)建可變數(shù)組,這里以一例子做說(shuō)明:
1 //創(chuàng)建空數(shù)組 2 NSMutableArray *array = [[NSMutableArray alloc] init]; 3 4 //插入5個(gè)數(shù)字,這里發(fā)生了裝箱 5 for (int i = 0; i < 5; i++) { 6 NSNumber *n = [NSNumber numberWithInt:i]; 7 [array addObject:n]; 8 } 9 10 //打印當(dāng)前長(zhǎng)度11 NSLog(@"%d", [array count]);12 13 //在第二個(gè)元素后插入程咬金14 [array insertObject:@"程咬金" atIndex:2];15 16 //刪除第一個(gè)元素17 [array removeObjectAtIndex:0];18 19 NSString *s =[array componentsJoinedByString:@"|"];20 21 //輸出字符串,|隔開(kāi)22 NSLog(@"%@", s);23 24 //字符串轉(zhuǎn)回來(lái)25 NSArray *a = [s componentsSeparatedByString:@"1"];26 27 for(id item in array){28 NSLog(@"%@", item);29 }30 31 for(id item in a){32 NSLog(@"%@", item);33 }
前面簡(jiǎn)單介紹了OC中的數(shù)組,我們繼續(xù)回到我們本來(lái)的需求
后面會(huì)用到字符串相關(guān)的知識(shí)點(diǎn),我們這里順便說(shuō)一下OC的字符串,事實(shí)上NSString是一個(gè)類,所以我們實(shí)例化的時(shí)候是指針引用,字符串的實(shí)例化不是我們關(guān)注的重點(diǎn),這次的重點(diǎn)放在,字符串的比較與操作,這個(gè)是我們后面項(xiàng)目會(huì)遇到的。
length可以返回字符串長(zhǎng)度
1 NSString *s = @"sdsdsdds";2 NSLog(@"%d", [s length]);//=>8
字符串比較的場(chǎng)景一定會(huì)碰到,OC的字符串比較
1 NSString *s = @"sdsdsdds";2 NSString *s1 = @"sdsdsdds";3 NSString *s2 = @"sdsdsdds1";4 5 NSLog(@"%i", [s isEqualToString:s1]);//=>16 NSLog(@"%i", [s isEqualToString:s2]);//=>0
1 NSString *s = @"sdsdsdds"; 2 NSString *s1 = @"1sdsdsdds"; 3 NSString *s2 = @"2sdsdsdds1"; 4 5 NSLog(@"%i", [s isEqualToString:s1]);//=>1 6 NSLog(@"%i", [s isEqualToString:s2]);//=>0 7 8 //NSOrderedDescending|NSOrderedAscending 9 //NSOrderedAscending判斷兩對(duì)象值的大小(按字母順序進(jìn)行比較)10 BOOL result = [s1 compare:s2] == NSOrderedAscending;11 NSLog(@"result:%d",result);//=>1=>true
1 NSString *s1 = @"1sdsdsdds";2 NSString *s2 = @"2sdsdsdds1";3 4 NSLog(@"%@", [s1 stringByAppendingString:s2]);
我們使用一個(gè)可變數(shù)組裝在我們的學(xué)生,并且錄入3條數(shù)據(jù),最后以他們的總分排序,我們這里先
1 //創(chuàng)建學(xué)生集合 2 NSMutableArray *students = [[NSMutableArray alloc] init]; 3 Student *student; 4 5 //下面代碼可能會(huì)出現(xiàn)警告信息,以我現(xiàn)在的熟悉度是肯定不知道為什么,而且我暫時(shí)也不會(huì)關(guān)注 6 for(int i = 0; i < 5; i++) { 7 //初始化臨時(shí)學(xué)生變量,插入數(shù)組 8 student = [[Student alloc] 9 initWithName:[@"姓名_" stringByAppendingString: [NSString stringWithFormat:@"%d", i]]10 andAge:(18 + arc4random() % 4)11 andSex:(arc4random() % 2 == 0 ? @"男" : @"女")12 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:arc4random() % 101]13 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:arc4random() % 101]];14 [students addObject:student];15 }16 17 for(id item in students){18 [item showData];19 }
這里會(huì)打印出每個(gè)學(xué)生的東西:
2015-08-09 11:46:23.380 student[5454:444911] 姓名:姓名_02015-08-09 11:46:23.382 student[5454:444911] 性別:女2015-08-09 11:46:23.382 student[5454:444911] 年齡:202015-08-09 11:46:23.387 student[5454:444911] 入學(xué)時(shí)間:2015-08-09 03:46:23 +00002015-08-09 11:46:23.387 student[5454:444911] 課程名:語(yǔ)文2015-08-09 11:46:23.388 student[5454:444911] 課程得分:59.0000002015-08-09 11:46:23.388 student[5454:444911] 課程名:數(shù)學(xué)2015-08-09 11:46:23.388 student[5454:444911] 課程得分:7.0000002015-08-09 11:46:23.388 student[5454:444911] 姓名:姓名_12015-08-09 11:46:23.388 student[5454:444911] 性別:女2015-08-09 11:46:23.389 student[5454:444911] 年齡:202015-08-09 11:46:23.389 student[5454:444911] 入學(xué)時(shí)間:2015-08-09 03:46:23 +00002015-08-09 11:46:23.389 student[5454:444911] 課程名:語(yǔ)文2015-08-09 11:46:23.389 student[5454:444911] 課程得分:79.0000002015-08-09 11:46:23.389 student[5454:444911] 課程名:數(shù)學(xué)2015-08-09 11:46:23.390 student[5454:444911] 課程得分:13.0000002015-08-09 11:46:23.390 student[5454:444911] 姓名:姓名_22015-08-09 11:46:23.390 student[5454:444911] 性別:女2015-08-09 11:46:23.390 student[5454:444911] 年齡:182015-08-09 11:46:23.390 student[5454:444911] 入學(xué)時(shí)間:2015-08-09 03:46:23 +00002015-08-09 11:46:23.391 student[5454:444911] 課程名:語(yǔ)文2015-08-09 11:46:23.391 student[5454:444911] 課程得分:87.0000002015-08-09 11:46:23.391 student[5454:444911] 課程名:數(shù)學(xué)2015-08-09 11:46:23.391 student[5454:444911] 課程得分:52.0000002015-08-09 11:46:23.391 student[5454:444911] 姓名:姓名_32015-08-09 11:46:23.392 student[5454:444911] 性別:女2015-08-09 11:46:23.392 student[5454:444911] 年齡:182015-08-09 11:46:23.392 student[5454:444911] 入學(xué)時(shí)間:2015-08-09 03:46:23 +00002015-08-09 11:46:23.392 student[5454:444911] 課程名:語(yǔ)文2015-08-09 11:46:23.393 student[5454:444911] 課程得分:13.0000002015-08-09 11:46:23.393 student[5454:444911] 課程名:數(shù)學(xué)2015-08-09 11:46:23.393 student[5454:444911] 課程得分:74.0000002015-08-09 11:46:23.393 student[5454:444911] 姓名:姓名_42015-08-09 11:46:23.393 student[5454:444911] 性別:女2015-08-09 11:46:23.394 student[5454:444911] 年齡:182015-08-09 11:46:23.394 student[5454:444911] 入學(xué)時(shí)間:2015-08-09 03:46:23 +00002015-08-09 11:46:23.394 student[5454:444911] 課程名:語(yǔ)文2015-08-09 11:46:23.394 student[5454:444911] 課程得分:77.0000002015-08-09 11:46:23.394 student[5454:444911] 課程名:數(shù)學(xué)2015-08-09 11:46:23.395 student[5454:444911] 課程得分:58.000000Program ended with exit code: 0
1 //創(chuàng)建學(xué)生集合 2 NSMutableArray *students = [[NSMutableArray alloc] init]; 3 Student *student; 4 5 6 //下面代碼可能會(huì)出現(xiàn)警告信息,以我現(xiàn)在的熟悉度是肯定不知道為什么,而且我暫時(shí)也不會(huì)關(guān)注 7 for(int i = 0; i < 5; i++) { 8 //初始化臨時(shí)學(xué)生變量,插入數(shù)組 9 student = [[Student alloc]10 initWithName:[@"姓名_" stringByAppendingString: [NSString stringWithFormat:@"%d", i]]11 andAge:(18 + arc4random() % 4)12 andSex:(arc4random() % 2 == 1 ? @"男" : @"女")13 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:arc4random() % 101]14 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:arc4random() % 101]];15 [students addObject:student];16 }17 18 //這里做按考試總分排序的功能,也許是我不夠熟悉,但這里真心不得不說(shuō)寫(xiě)慣了js,尼瑪OC的語(yǔ)法真令人蛋疼!!!19 NSArray *sortArray = [students sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){20 //這里不知道為什么不能使用obj1的點(diǎn)語(yǔ)法了21 if ([obj1 chinese].score + [obj1 math].score > [obj2 chinese].score + [obj2 math].score) {22 return (NSComparisonResult)NSOrderedDescending;23 }24 if ([obj1 chinese].score + [obj1 math].score < [obj2 chinese].score + [obj2 math].score) {25 return (NSComparisonResult)NSOrderedAscending;26 }27 return (NSComparisonResult)NSOrderedSame;28 }];29 30 for(id item in students){31 [item showData];32 }33 34 NSLog(@"=====排序后======/n");35 36 for(id item in sortArray){37 [item showData];38 }
輸出:

2015-08-09 12:59:45.483 student[5720:468194] 姓名:姓名_02015-08-09 12:59:45.484 student[5720:468194] 性別:女2015-08-09 12:59:45.484 student[5720:468194] 年齡:192015-08-09 12:59:45.485 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.485 student[5720:468194] 課程得分:54.02015-08-09 12:59:45.485 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.485 student[5720:468194] 課程得分:60.02015-08-09 12:59:45.485 student[5720:468194] 考試總分:114.02015-08-09 12:59:45.486 student[5720:468194] -------------2015-08-09 12:59:45.486 student[5720:468194] 姓名:姓名_12015-08-09 12:59:45.486 student[5720:468194] 性別:男2015-08-09 12:59:45.486 student[5720:468194] 年齡:182015-08-09 12:59:45.486 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.486 student[5720:468194] 課程得分:33.02015-08-09 12:59:45.487 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.487 student[5720:468194] 課程得分:85.02015-08-09 12:59:45.487 student[5720:468194] 考試總分:118.02015-08-09 12:59:45.487 student[5720:468194] -------------2015-08-09 12:59:45.487 student[5720:468194] 姓名:姓名_22015-08-09 12:59:45.487 student[5720:468194] 性別:女2015-08-09 12:59:45.540 student[5720:468194] 年齡:192015-08-09 12:59:45.541 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.541 student[5720:468194] 課程得分:98.02015-08-09 12:59:45.541 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.541 student[5720:468194] 課程得分:37.02015-08-09 12:59:45.541 student[5720:468194] 考試總分:135.02015-08-09 12:59:45.542 student[5720:468194] -------------2015-08-09 12:59:45.542 student[5720:468194] 姓名:姓名_32015-08-09 12:59:45.542 student[5720:468194] 性別:男2015-08-09 12:59:45.542 student[5720:468194] 年齡:182015-08-09 12:59:45.542 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.542 student[5720:468194] 課程得分:69.02015-08-09 12:59:45.543 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.543 student[5720:468194] 課程得分:1.02015-08-09 12:59:45.543 student[5720:468194] 考試總分:70.02015-08-09 12:59:45.543 student[5720:468194] -------------2015-08-09 12:59:45.543 student[5720:468194] 姓名:姓名_42015-08-09 12:59:45.543 student[5720:468194] 性別:女2015-08-09 12:59:45.543 student[5720:468194] 年齡:202015-08-09 12:59:45.544 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.544 student[5720:468194] 課程得分:88.02015-08-09 12:59:45.560 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.560 student[5720:468194] 課程得分:16.02015-08-09 12:59:45.561 student[5720:468194] 考試總分:104.02015-08-09 12:59:45.561 student[5720:468194] -------------2015-08-09 12:59:45.561 student[5720:468194] =====排序后======2015-08-09 12:59:45.562 student[5720:468194] 姓名:姓名_32015-08-09 12:59:45.562 student[5720:468194] 性別:男2015-08-09 12:59:45.562 student[5720:468194] 年齡:182015-08-09 12:59:45.563 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.563 student[5720:468194] 課程得分:69.02015-08-09 12:59:45.563 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.563 student[5720:468194] 課程得分:1.02015-08-09 12:59:45.564 student[5720:468194] 考試總分:70.02015-08-09 12:59:45.564 student[5720:468194] -------------2015-08-09 12:59:45.564 student[5720:468194] 姓名:姓名_42015-08-09 12:59:45.564 student[5720:468194] 性別:女2015-08-09 12:59:45.565 student[5720:468194] 年齡:202015-08-09 12:59:45.565 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.565 student[5720:468194] 課程得分:88.02015-08-09 12:59:45.565 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.566 student[5720:468194] 課程得分:16.02015-08-09 12:59:45.566 student[5720:468194] 考試總分:104.02015-08-09 12:59:45.603 student[5720:468194] -------------2015-08-09 12:59:45.603 student[5720:468194] 姓名:姓名_02015-08-09 12:59:45.603 student[5720:468194] 性別:女2015-08-09 12:59:45.603 student[5720:468194] 年齡:192015-08-09 12:59:45.604 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.604 student[5720:468194] 課程得分:54.02015-08-09 12:59:45.604 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.604 student[5720:468194] 課程得分:60.02015-08-09 12:59:45.604 student[5720:468194] 考試總分:114.02015-08-09 12:59:45.605 student[5720:468194] -------------2015-08-09 12:59:45.605 student[5720:468194] 姓名:姓名_12015-08-09 12:59:45.605 student[5720:468194] 性別:男2015-08-09 12:59:45.605 student[5720:468194] 年齡:182015-08-09 12:59:45.605 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.605 student[5720:468194] 課程得分:33.02015-08-09 12:59:45.606 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.606 student[5720:468194] 課程得分:85.02015-08-09 12:59:45.606 student[5720:468194] 考試總分:118.02015-08-09 12:59:45.606 student[5720:468194] -------------2015-08-09 12:59:45.606 student[5720:468194] 姓名:姓名_22015-08-09 12:59:45.606 student[5720:468194] 性別:女2015-08-09 12:59:45.607 student[5720:468194] 年齡:192015-08-09 12:59:45.607 student[5720:468194] 課程名:語(yǔ)文2015-08-09 12:59:45.626 student[5720:468194] 課程得分:98.02015-08-09 12:59:45.626 student[5720:468194] 課程名:數(shù)學(xué)2015-08-09 12:59:45.626 student[5720:468194] 課程得分:37.02015-08-09 12:59:45.627 student[5720:468194] 考試總分:135.02015-08-09 12:59:45.627 student[5720:468194] -------------Program ended with exit code: 0
完整的代碼:

1 #import <Foundation/Foundation.h> 2 3 @interface Course : NSObject 4 { 5 NSString *_name; 6 float _score; 7 } 8 9 -(instancetype)initWithName:(NSString *)newName andScore:(float)newScore; 10 11 -(void)setName: (NSString *)str; 12 -(NSString *)name; 13 14 -(void)setScore: (float)fl; 15 -(float)score; 16 17 -(void)showData; 18 19 @end 20 21 #import "Course.h" 22 23 @implementation Course 24 25 //自定義構(gòu)造方法 26 -(instancetype)initWithName:(NSString *)newName andScore:(float)newScore 27 { 28 self = [super init]; 29 if (self) { 30 _name = newName; 31 _score = newScore; 32 } 33 return self; 34 } 35 36 -(void) setName:(NSString *)str 37 { 38 _name = str; 39 } 40 41 -(NSString *) name 42 { 43 return _name; 44 } 45 46 -(void) setScore:(float)fl 47 { 48 _score = fl; 49 } 50 51 -(float) score 52 { 53 return _score; 54 } 55 56 -(void) showData 57 { 58 NSLog(@"課程名:%@", _name); 59 NSLog(@"課程得分:%.1f",_score); 60 } 61 62 @end 63 64 #import <Foundation/Foundation.h> 65 #import "Course.h" 66 67 @interface Student : NSObject 68 { 69 NSString *_name; 70 int _age; 71 NSString *_sex; 72 Course *_chinese; 73 Course *_math; 74 //錄入時(shí)間 75 NSDate *_dateCreate; 76 } 77 78 -(instancetype)initWithName:(NSString *)newName andAge:(int)newAge andSex:(NSString *)newSex andChinese:(Course *) newChinese andMath:(Course *) newMath; 79 80 -(void)setName: (NSString *)str; 81 -(NSString *)name; 82 83 -(void)setAge: (int)a; 84 -(int)age; 85 86 -(void)setSex: (NSString *)str; 87 -(NSString *)sex; 88 89 -(void)setChinese: (Course *)c; 90 -(Course *)chinese; 91 92 -(void)setMath: (Course *)c; 93 -(Course *)math; 94 95 //只暴露讀取接口 96 -(NSDate *)dateCreate; 97 98 -(void) showData; 99 100 @end101 102 #import "Student.h"103 104 @implementation Student105 106 -(instancetype)initWithName:(NSString *)newName andAge:(int)newAge andSex:(NSString *)newSex andChinese:(Course *) newChinese andMath:(Course *) newMath107 {108 self = [super init];109 if (self) {110 _name = newName;111 _age = newAge;112 _sex = newSex;113 _chinese = newChinese;114 _math = newMath;115 _dateCreate = [[NSDate alloc] init];116 }117 return self;118 }119 120 -(void) setName:(NSString *)str121 {122 _name = str;123 }124 125 -(NSString *) name126 {127 return _name;128 }129 130 -(void)setAge: (int)a131 {132 _age = a;133 }134 135 -(int)age136 {137 return _age;138 }139 140 -(void)setSex: (NSString *)str141 {142 _sex = str;143 }144 145 -(NSString *)sex146 {147 return _sex;148 }149 150 -(void)setChinese: (Course *)c151 {152 _chinese = c;153 }154 155 -(Course *)chinese156 {157 return _chinese;158 }159 160 -(void)setMath: (Course *)c161 {162 _math = c;163 }164 165 -(Course *)math166 {167 return _math;168 }169 170 //只暴露讀取接口171 -(NSDate *)dateCreate172 {173 return _dateCreate;174 }175 176 -(void) showData177 {178 NSLog(@"姓名:%@", _name);179 NSLog(@"性別:%@", _sex);180 NSLog(@"年齡:%d", _age);181 //NSLog(@"入學(xué)時(shí)間:%@", _dateCreate);182 [_chinese showData];183 [_math showData];184 NSLog(@"考試總分:%.1f", _chinese.score + _math.score);185 NSLog(@"-------------/n");186 }187 188 @end189 190 #import <Foundation/Foundation.h>191 #import "Student.h"192 #import "Course.h"193 194 int main(int argc, const char * argv[]) {195 @autoreleasepool {196 197 //創(chuàng)建學(xué)生集合198 NSMutableArray *students = [[NSMutableArray alloc] init];199 Student *student;200 201 202 //下面代碼可能會(huì)出現(xiàn)警告信息,以我現(xiàn)在的熟悉度是肯定不知道為什么,而且我暫時(shí)也不會(huì)關(guān)注203 for(int i = 0; i < 5; i++) {204 //初始化臨時(shí)學(xué)生變量,插入數(shù)組205 student = [[Student alloc]206 initWithName:[@"姓名_" stringByAppendingString: [NSString stringWithFormat:@"%d", i]]207 andAge:(18 + arc4random() % 4)208 andSex:(arc4random() % 2 == 1 ? @"男" : @"女")209 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:arc4random() % 101]210 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:arc4random() % 101]];211 [students addObject:student];212 }213 214 //這里做按考試總分排序的功能,也許是我不夠熟悉,但這里真心不得不說(shuō)寫(xiě)慣了js,尼瑪OC的語(yǔ)法真令人蛋疼?。。?/span>215 NSArray *sortArray = [students sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){216 //這里不知道為什么不能使用obj1的點(diǎn)語(yǔ)法了217 if ([obj1 chinese].score + [obj1 math].score > [obj2 chinese].score + [obj2 math].score) {218 return (NSComparisonResult)NSOrderedDescending;219 }220 if ([obj1 chinese].score + [obj1 math].score < [obj2 chinese].score + [obj2 math].score) {221 return (NSComparisonResult)NSOrderedAscending;222 }223 return (NSComparisonResult)NSOrderedSame;224 }];225 226 for(id item in students){227 [item showData];228 }229 230 NSLog(@"=====排序后======/n");231 232 for(id item in sortArray){233 [item showData];234 }235 236 }237 return 0;238 }
控制臺(tái)輸出部分完成后,我們的功能也就實(shí)現(xiàn)了一半,現(xiàn)在要做的是,如何將上述功能寫(xiě)到app中,意思是我們現(xiàn)在就要開(kāi)始做app開(kāi)發(fā)了,因?yàn)槲覜](méi)有開(kāi)發(fā)者賬號(hào),只能在mac上模擬。
既然是app就應(yīng)該有更加完善的功能了,這里給自己的需求是:
1 有界面錄入學(xué)生信息
2 有列表可展示學(xué)生信息
3 學(xué)生信息可排序
4 可編輯、刪除學(xué)生
需求不多,多了可能就做不完,于是我們便愉快的開(kāi)始吧,這次新建項(xiàng)目會(huì)有所不同:選擇的是最簡(jiǎn)單的single View application
這里取個(gè)名字student_app,完了就會(huì)在模擬器中新增一個(gè)app,瞬間覺(jué)得好牛B的樣子:

然后,項(xiàng)目中的文件以及界面讓我感覺(jué)到了陌生,這里也不一一去了解了,直接朝著需求方向進(jìn)發(fā)吧。
PS:學(xué)習(xí)過(guò)程中最初會(huì)有意的忽略一些基礎(chǔ)知識(shí),但是這些知識(shí)是我們后面能走多遠(yuǎn)的基礎(chǔ),所以在快速熟悉后需要一個(gè)過(guò)渡期重新回來(lái)整理基礎(chǔ),否則走不遠(yuǎn)的
模型-視圖-控制器,是我們經(jīng)常聽(tīng)到的mvc,為各種與界面相關(guān)的系統(tǒng)都會(huì)頻繁使用的一種模式,其意義在于代碼解耦,OC APP開(kāi)發(fā)遵循這一規(guī)則
視圖簡(jiǎn)單來(lái)說(shuō)便是界面,比如我們后面要做的展示學(xué)生相關(guān)信息的界面
模型便是界面的數(shù)據(jù)來(lái)源
而控制器便是管理者,用于控制視圖與模型之間的交互,比如新增刪除什么的
于是,我們便開(kāi)始了解OC中MVC是如何使用的吧,也許學(xué)過(guò)后會(huì)幫助我們更加了解web中的MVC,偶爾我仍然覺(jué)得自己了解的不夠深刻
在此之前,我們先來(lái)了解幾個(gè)ios開(kāi)發(fā)的基本組件,否則將使我們的開(kāi)發(fā)無(wú)法繼續(xù)。
PS:從IOS5開(kāi)始進(jìn)行了改進(jìn),使用“.storyboard”文件進(jìn)行設(shè)計(jì)
UILabel繼承至UIView,這個(gè)名字讓我想起了多年前做.net2.0拖控件的時(shí)光,可能他們完成的功能也差不多,做展示性工作
這里新建一個(gè)文件:StudentViewController,繼承至UIViewController,這里記得勾選also create xib file,會(huì)生成如下文件:
file.h 頭文件file.m 實(shí)現(xiàn)文件file.xib xml interface build
這個(gè)xml文件有點(diǎn)類似與html文件,做布局用的,最初在左.net開(kāi)發(fā)winform窗體軟件時(shí),也會(huì)出現(xiàn)類似的文件,這里點(diǎn)擊打開(kāi),果然是一個(gè)白板窗體。
這里使用一種界面工具打開(kāi)該文件(interface builder),左側(cè)是dock,右邊是畫(huà)布,那坨東西與html一樣,事實(shí)上是一坨代碼:

1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyaccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3 <dependencies> 4 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/> 5 </dependencies> 6 <objects> 7 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="StudentViewController"> 8 <connections> 9 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>10 </connections>11 </placeholder>12 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>13 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">14 <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>15 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>16 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>17 </view>18 </objects>19 </document>

placeholder為占位符對(duì)象,下面那個(gè)是view對(duì)象,雖然不知道是什么,好像很厲害的樣子。
要使用UILabel,根據(jù)之前的開(kāi)發(fā)經(jīng)驗(yàn)估計(jì)會(huì)有兩種:
1 自己編輯代碼
2 ide會(huì)有工具箱讓我們拖
果不其然,這里便出現(xiàn)了對(duì)象庫(kù):在工具區(qū)域打開(kāi)對(duì)象庫(kù),位于編輯區(qū)的右側(cè),分為上下兩部分,檢視面板與庫(kù)面板,前者負(fù)責(zé)顯示編輯區(qū)域當(dāng)前選擇文件的各種設(shè)置;后者便是可拖拽的工具了:

因?yàn)槲覀兘⒌氖莝igile page application,所以上述文件不需要我們創(chuàng)建,系統(tǒng)自動(dòng)為我們創(chuàng)建好了Main.storyboard,我們之間在這之上開(kāi)發(fā)就行
我一次性拖了3個(gè)組件上去,視圖效果有所不同了,可以通過(guò)檢視面板調(diào)整屬性,雙擊按鈕可以編輯一些title,并可以設(shè)置居中等操作,這些需要我們慢慢熟悉

這個(gè)時(shí)候可以看到起代碼(類似與html的代碼)也發(fā)生了改變,我個(gè)人暫時(shí)沒(méi)有意愿去讀取,也希望以后都不需要去讀取......
所有的xib文件都會(huì)被編譯成nib文件,其體積更小,更容易解析,然后Xcode會(huì)將nib拷貝至程序包,包含可運(yùn)行的所有資源,這個(gè)不是我們?nèi)缃耜P(guān)注的重點(diǎn)
在了解如何設(shè)置關(guān)聯(lián)前,我們來(lái)看看代碼組織,我們知道OC的入口函數(shù)為main函數(shù),這里的main函數(shù)是:
1 #import <UIKit/UIKit.h>2 #import "AppDelegate.h"3 4 int main(int argc, char * argv[]) {5 @autoreleasepool {6 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));7 }8 }
這里制造了一個(gè)內(nèi)部消息循環(huán),我猜測(cè)這里開(kāi)了一個(gè)監(jiān)聽(tīng)進(jìn)程,不停的監(jiān)聽(tīng)view的變化,應(yīng)該有一個(gè)頻率,但是這與我們沒(méi)有一毛錢(qián)關(guān)系
這里調(diào)用了4個(gè)參數(shù),開(kāi)始兩個(gè)是main函數(shù)自帶的參數(shù)。
第三個(gè)參數(shù)為一個(gè)UIApplication(或子類)字符串,為nil便默認(rèn)為UIApplication,這個(gè)參數(shù)干什么的也暫時(shí)不知道
最后一個(gè)參數(shù)為UIApplication的代理字符串,默認(rèn)生成AppDelegate類,用于監(jiān)聽(tīng)整個(gè)應(yīng)用程序周期的各個(gè)事件,當(dāng)某個(gè)系統(tǒng)事件觸發(fā)便會(huì)執(zhí)行其代理中對(duì)應(yīng)方法
雖然不知道這一段代碼真實(shí)做了什么事情,但可猜測(cè)是這里會(huì)根據(jù)參數(shù)3創(chuàng)建UIApplication對(duì)象,然后根據(jù)第一個(gè)參數(shù)創(chuàng)建并指定UIApplication的代理,然后UIApplication便開(kāi)啟消息循環(huán)直到進(jìn)程被殺死,所以詳細(xì)代表在AppDelegate中:
1 #import <UIKit/UIKit.h>2 3 @interface AppDelegate : UIResponder <UIApplicationDelegate>4 5 @property (strong, nonatomic) UIWindow *window;6 7 8 @end
1 #import "AppDelegate.h" 2 3 @interface AppDelegate () 4 5 @end 6 7 @implementation AppDelegate 8 9 10 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {11 // Override point for customization after application launch.12 return YES;13 }14 15 - (void)applicationWillResignActive:(UIApplication *)application {16 // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.17 // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.18 }19 20 - (void)applicationDidEnterBackground:(UIApplication *)application {21 // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.22 // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.23 }24 25 - (void)applicationWillEnterForeground:(UIApplication *)application {26 // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.27 }28 29 - (void)applicationDidBecomeActive:(UIApplication *)application {30 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.31 }32 33 - (void)applicationWillTerminate:(UIApplication *)application {34 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.35 }36 37 @end
這個(gè)類中定義了應(yīng)用程序生命周期中各個(gè)事件的執(zhí)行方法:- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
程序啟動(dòng)之后執(zhí)行,只有在第一次程序啟動(dòng)后才執(zhí)行,以后不再執(zhí)行;- (void)applicationWillResignActive:(UIApplication *)application;
程序?qū)⒁患せ顣r(shí)(獲得焦點(diǎn))執(zhí)行,程序激活用戶才能操作;- (void)applicationDidEnterBackground:(UIApplication *)application;
程序進(jìn)入后臺(tái)后執(zhí)行,注意進(jìn)入后臺(tái)時(shí)會(huì)先失去焦點(diǎn)再進(jìn)入后臺(tái);- (void)applicationWillEnterForeground:(UIApplication *)application;
程序?qū)⒁M(jìn)入前臺(tái)時(shí)執(zhí)行;- (void)applicationDidBecomeActive:(UIApplication *)application;
程序被激活(獲得焦點(diǎn))后執(zhí)行,注意程序被激活時(shí)會(huì)先進(jìn)入前臺(tái)再被激活;- (void)applicationWillTerminate:(UIApplication *)application;
程序在終止時(shí)執(zhí)行,包括正常終止或異常終止,例如說(shuō)一個(gè)應(yīng)用程序在后太運(yùn)行(例如音樂(lè)播放軟件、社交軟件等)占用太多內(nèi)存這時(shí)會(huì)意外終止調(diào)用此方法;這個(gè)有點(diǎn)類似與.net application的事件管道,在一條程序生命周期內(nèi),當(dāng)達(dá)到某一個(gè)特定的時(shí)期便會(huì)執(zhí)行相關(guān)函數(shù),這里我們不去深入了解,事實(shí)上與我們當(dāng)前需求意義不大
下面是其文件具體含義:
AppDelegate(.h/.m):應(yīng)用程序代理,主要用于監(jiān)聽(tīng)整個(gè)應(yīng)用程序生命周期中各個(gè)階段的事件;ViewController(.h/.m):視圖控制器,主要負(fù)責(zé)管理UIView的生命周期、負(fù)責(zé)UIView之間的切換、對(duì)UIView事件進(jìn)行監(jiān)聽(tīng)等;Main.storyboard:界面布局文件,承載對(duì)應(yīng)UIView的視圖控件;Images.xcassets:應(yīng)用程序圖像資源文件;Info.plist:應(yīng)用程序配置文件;main.m:應(yīng)用程序入口函數(shù)文件;xxx-prefix.pch:項(xiàng)目公共頭文件,此文件中的導(dǎo)入語(yǔ)句在編譯時(shí)會(huì)應(yīng)用到所有的類文件中,相當(dāng)于公共引入文件(注意在Xcode6中沒(méi)有提供此文件)以上有3個(gè)UI對(duì)象,但是是沒(méi)有交互的,interface builder可以創(chuàng)建兩種關(guān)聯(lián):
① 插座變量一種指向?qū)ο蟮闹羔槩?動(dòng)作變量一種方法,比如點(diǎn)擊、拖拽等事件根據(jù)之前的經(jīng)驗(yàn),插座變量應(yīng)該便是id相關(guān)映射,動(dòng)作變量便是事件回調(diào)我們知道關(guān)聯(lián)相關(guān)的代碼肯定在控制器中,這個(gè)時(shí)候便需要對(duì)控制器文件進(jìn)行操作,我們首先在頭文件中創(chuàng)建3個(gè)對(duì)象,兩個(gè)插座對(duì)象,一個(gè)事件對(duì)象:
1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UIViewController 4 5 //屬性簡(jiǎn)單創(chuàng)建的語(yǔ)法糖,后續(xù)需要詳細(xì)了解其用法 6 @property (nonatomic, strong) IBOutlet UILabel *msg; 7 8 @property (nonatomic, strong) IBOutlet UITextField *txt; 9 10 //點(diǎn)擊按鈕后的事件回調(diào)11 -(IBAction)myClick:(UIButton *)btn;12 13 @end
IBOutlet 沒(méi)有實(shí)際意義,他會(huì)告訴interface builder這個(gè)屬性會(huì)被關(guān)聯(lián)到某個(gè)控件,代碼前面也確實(shí)出現(xiàn)了小圓點(diǎn):

所謂的關(guān)聯(lián)便是在畫(huà)板中將對(duì)應(yīng)的控件拖向小圓點(diǎn),這里OC又一次沒(méi)有讓我們失望,依舊那么惡心,當(dāng)我得知我要拖動(dòng)時(shí),我感覺(jué)整個(gè)智商又降低了!步驟為:
點(diǎn)擊右上方的show the assistant editor,打開(kāi)控制器文件與視圖文件開(kāi)始拖拽吧?。。?/p>

這里只說(shuō)明拖動(dòng),可關(guān)聯(lián),不要關(guān)注實(shí)際代碼。下面看看改動(dòng)controller代碼會(huì)如何,這里增加按鈕點(diǎn)擊時(shí)的實(shí)現(xiàn):
1 #import "ViewController.h" 2 3 @interface ViewController () 4 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad {10 [super viewDidLoad];11 // Do any additional setup after loading the view, typically from a nib.12 }13 14 - (void)didReceiveMemoryWarning {15 [super didReceiveMemoryWarning];16 // Dispose of any resources that can be recreated.17 }18 19 //讓label顯示文本框的文字20 -(void) myClick:(UIButton *)btn{21 _msg.text = _txt.text;22 }23 24 @end

其中UI組件的具體使用我們暫時(shí)不予關(guān)注,再后面的章節(jié)中再好好鞏固基礎(chǔ),或者后續(xù)項(xiàng)目中好好總結(jié)......
說(shuō)是使用面部做簡(jiǎn)單界面設(shè)計(jì)是可以的,也是贊成的,但是要使用拖拽的方式關(guān)聯(lián)控件和事件還是算了吧,詳細(xì).net的雙擊按鈕生成事件真心優(yōu)雅多了,當(dāng)然OC也是可以純代碼做這些事情的,這個(gè)留待我們下次處理,否則今天的學(xué)習(xí)任務(wù)便結(jié)束不了了。
這里先回答學(xué)生管理系統(tǒng)本身學(xué)生類與課程類之前已經(jīng)創(chuàng)建結(jié)束,這里我們看界面應(yīng)該如何開(kāi)發(fā)其界面,由于時(shí)間關(guān)系,也不去使用什么單選框,直接全部上文本框吧,尼瑪太久沒(méi)寫(xiě)博客發(fā)現(xiàn)居然會(huì)有點(diǎn)累?。?!
這里首先建立了這樣的視圖,并且按照之前拖拽的方式建立了管理,其中按鈕只有事件關(guān)聯(lián)

這里簡(jiǎn)單測(cè)試,效果還是可行的:
1 //這里實(shí)例化一個(gè)Student對(duì)象試試 2 //這里如果數(shù)字輸入錯(cuò)誤會(huì)導(dǎo)致解析出問(wèn)題,可能會(huì)報(bào)錯(cuò),不知道OC生產(chǎn)項(xiàng)目應(yīng)該如何處理 3 Student *student = [[Student alloc] 4 initWithName:_stuName.text 5 andAge:[_stuAge.text intValue] 6 andSex:_stuSex.text 7 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:[_stuChinese.text floatValue]] 8 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:[_stuMath.text floatValue]]]; 9 10 [student showData];
2015-08-09 20:01:10.273 student_app[7140:619984] 姓名:112015-08-09 20:01:10.274 student_app[7140:619984] 性別:男2015-08-09 20:01:10.275 student_app[7140:619984] 年齡:222015-08-09 20:01:10.275 student_app[7140:619984] 課程名:語(yǔ)文2015-08-09 20:01:10.276 student_app[7140:619984] 課程得分:33.02015-08-09 20:01:10.276 student_app[7140:619984] 課程名:數(shù)學(xué)2015-08-09 20:01:10.276 student_app[7140:619984] 課程得分:44.02015-08-09 20:01:10.277 student_app[7140:619984] 考試總分:77.02015-08-09 20:01:10.277 student_app[7140:619984] -------------
于是我們回到最初的做法,每次錄入皆將數(shù)據(jù)放進(jìn)一個(gè)數(shù)組中,由于這個(gè)數(shù)組是固定的,這里將之作為控制器的一個(gè)屬性,生產(chǎn)是怎么樣的我們后面看看,于是在控制器上建立students的成員屬性。
每次添加到數(shù)組中,然后將數(shù)組中的數(shù)組展示出來(lái)即可,這里展示數(shù)據(jù)得使用一個(gè)非常常見(jiàn)的列表組件:UITableView
UITableView是OC中經(jīng)常使用的組件,主要用于顯示列表,這個(gè)組件比較復(fù)雜真的要研究恐怕得研究1,2天,我們這邊就直接看其如何使用即可,這里的目標(biāo)便是將錄入的數(shù)據(jù)顯示在界面上,我們今天的任務(wù)便完成。
這里在控制器頭文件中新增一個(gè)UITableView組件,然后嘗試綁定即可,經(jīng)過(guò)漫長(zhǎng)的研究,最終成果是:

雖然有點(diǎn)丑,但是基本符合預(yù)期,而編輯等功能就等下次再完成了,今天沒(méi)有精力了,一下是一些代碼:

1 #import <Foundation/Foundation.h> 2 3 @interface Course : NSObject 4 { 5 NSString *_name; 6 float _score; 7 } 8 9 -(instancetype)initWithName:(NSString *)newName andScore:(float)newScore; 10 11 -(void)setName: (NSString *)str; 12 -(NSString *)name; 13 14 -(void)setScore: (float)fl; 15 -(float)score; 16 17 -(void)showData; 18 19 @end 20 21 #import "Course.h" 22 23 @implementation Course 24 25 //自定義構(gòu)造方法 26 -(instancetype)initWithName:(NSString *)newName andScore:(float)newScore 27 { 28 self = [super init]; 29 if (self) { 30 _name = newName; 31 _score = newScore; 32 } 33 return self; 34 } 35 36 -(void) setName:(NSString *)str 37 { 38 _name = str; 39 } 40 41 -(NSString *) name 42 { 43 return _name; 44 } 45 46 -(void) setScore:(float)fl 47 { 48 _score = fl; 49 } 50 51 -(float) score 52 { 53 return _score; 54 } 55 56 -(void) showData 57 { 58 NSLog(@"課程名:%@", _name); 59 NSLog(@"課程得分:%.1f",_score); 60 } 61 62 @end 63 64 #import <Foundation/Foundation.h> 65 #import "Course.h" 66 67 @interface Student : NSObject 68 { 69 NSString *_name; 70 int _age; 71 NSString *_sex; 72 Course *_chinese; 73 Course *_math; 74 //錄入時(shí)間 75 NSDate *_dateCreate; 76 } 77 78 -(instancetype)initWithName:(NSString *)newName andAge:(int)newAge andSex:(NSString *)newSex andChinese:(Course *) newChinese andMath:(Course *) newMath; 79 80 -(void)setName: (NSString *)str; 81 -(NSString *)name; 82 83 -(void)setAge: (int)a; 84 -(int)age; 85 86 -(void)setSex: (NSString *)str; 87 -(NSString *)sex; 88 89 -(void)setChinese: (Course *)c; 90 -(Course *)chinese; 91 92 -(void)setMath: (Course *)c; 93 -(Course *)math; 94 95 //只暴露讀取接口 96 -(NSDate *)dateCreate; 97 98 -(void) showData; 99 -(NSString *) getData;100 101 @end102 103 #import "Student.h"104 105 @implementation Student106 107 -(instancetype)initWithName:(NSString *)newName andAge:(int)newAge andSex:(NSString *)newSex andChinese:(Course *) newChinese andMath:(Course *) newMath108 {109 self = [super init];110 if (self) {111 _name = newName;112 _age = newAge;113 _sex = newSex;114 _chinese = newChinese;115 _math = newMath;116 _dateCreate = [[NSDate alloc] init];117 }118 return self;119 }120 121 -(void) setName:(NSString *)str122 {123 _name = str;124 }125 126 -(NSString *) name127 {128 return _name;129 }130 131 -(void)setAge: (int)a132 {133 _age = a;134 }135 136 -(int)age137 {138 return _age;139 }140 141 -(void)setSex: (NSString *)str142 {143 _sex = str;144 }145 146 -(NSString *)sex147 {148 return _sex;149 }150 151 -(void)setChinese: (Course *)c152 {153 _chinese = c;154 }155 156 -(Course *)chinese157 {158 return _chinese;159 }160 161 -(void)setMath: (Course *)c162 {163 _math = c;164 }165 166 -(Course *)math167 {168 return _math;169 }170 171 //只暴露讀取接口172 -(NSDate *)dateCreate173 {174 return _dateCreate;175 }176 177 -(void) showData178 {179 NSLog(@"姓名:%@", _name);180 NSLog(@"性別:%@", _sex);181 NSLog(@"年齡:%d", _age);182 //NSLog(@"入學(xué)時(shí)間:%@", _dateCreate);183 [_chinese showData];184 [_math showData];185 NSLog(@"考試總分:%.1f", _chinese.score + _math.score);186 NSLog(@"-------------/n");187 }188 189 -(NSString *) getData190 {191 return [[_name stringByAppendingString:@"總分 "]192 stringByAppendingString: [NSString stringWithFormat:@"%.1f",_chinese.score + _math.score]];193 }194 195 @end196 197 #import <UIKit/UIKit.h>198 #import "Student.h"199 200 //這里需要實(shí)現(xiàn)一個(gè)協(xié)議,就是我們說(shuō)的接口,原因后續(xù)再研究201 //delegate是為了數(shù)據(jù)更新時(shí)刷新視圖202 @interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>203 204 //存儲(chǔ)學(xué)生的集合205 @property (nonatomic, strong) NSMutableArray *students;206 207 //屬性簡(jiǎn)單創(chuàng)建的語(yǔ)法糖,后續(xù)需要詳細(xì)了解其用法208 @property (nonatomic, strong) IBOutlet UITextField *stuName;209 210 @property (nonatomic, strong) IBOutlet UITextField *stuSex;211 212 @property (nonatomic, strong) IBOutlet UITextField *stuAge;213 214 @property (nonatomic, strong) IBOutlet UITextField *stuChinese;215 216 @property (nonatomic, strong) IBOutlet UITextField *stuMath;217 218 @property (nonatomic, strong) IBOutlet UITableView *stuList;219 220 221 //點(diǎn)擊按鈕后的事件回調(diào)222 -(IBAction)onAdd:(UIButton *)btn;223 224 //點(diǎn)擊按鈕后的事件回調(diào)225 -(IBAction)onRead:(UIButton *)btn;226 227 @end228 229 #import "ViewController.h"230 #import "Course.h"231 #import "Student.h"232 233 @interface ViewController ()234 @end235 236 @implementation ViewController237 238 ////重寫(xiě)初始化方法,控制器對(duì)象創(chuàng)建結(jié)束后會(huì)執(zhí)行239 //240 //-(id) initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil{241 // 242 // self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];243 // 244 // if(self) {245 // self.students= [NSMutableArray alloc];246 // }247 // 248 // return self;249 //}250 251 - (void)viewDidLoad {252 [super viewDidLoad];253 254 //在頁(yè)面準(zhǔn)備前對(duì)數(shù)組進(jìn)行初始化255 _students = [[NSMutableArray alloc] init];256 257 // _students = [NSMutableArray arrayWithObjects:@"武漢",@"上海",@"北京",@"深圳",@"廣州",@"重慶",@"香港",@"臺(tái)海",@"天津", nil];258 //259 _stuList = [[UITableView alloc] initWithFrame:CGRectMake(0, 250, 520, 420)];260 261 //設(shè)置數(shù)據(jù)源,注意必須實(shí)現(xiàn)對(duì)應(yīng)的UITableViewDataSource協(xié)議262 _stuList.dataSource = self;263 264 //動(dòng)態(tài)添加265 [self.view addSubview:_stuList];266 267 }268 269 - (void)didReceiveMemoryWarning {270 [super didReceiveMemoryWarning];271 }272 273 -(void) onAdd:(UIButton *)btn{274 //這里實(shí)例化一個(gè)Student對(duì)象試試275 //這里如果數(shù)字輸入錯(cuò)誤會(huì)導(dǎo)致解析出問(wèn)題,可能會(huì)報(bào)錯(cuò),不知道OC生產(chǎn)項(xiàng)目應(yīng)該如何處理276 Student *student = [[Student alloc]277 initWithName:_stuName.text278 andAge:[_stuAge.text intValue]279 andSex:_stuSex.text280 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:[_stuChinese.text floatValue]]281 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:[_stuMath.text floatValue]]];282 283 //這里每次點(diǎn)擊,皆將結(jié)果存于全局?jǐn)?shù)組中284 [_students addObject:student];285 286 //每次數(shù)據(jù)更新便將對(duì)應(yīng)數(shù)據(jù)顯示在UITableView中287 [_stuList performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];288 289 }290 291 -(void) onRead:(UIButton *)btn{292 for(id item in _students){293 [item showData];294 }295 }296 297 //必須實(shí)現(xiàn)298 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath299 {300 static NSString *CellWithIdentifier = @"Cell";301 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];302 if (cell == nil) {303 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellWithIdentifier];304 }305 NSUInteger row = [indexPath row];306 cell.textLabel.text = [[_students objectAtIndex:row] getData];307 308 return cell;309 }310 311 //每個(gè)section下cell的個(gè)數(shù)(必須實(shí)現(xiàn))312 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{313 return _students.count;314 }315 316 @end
核心代碼為:
1 #import "ViewController.h" 2 #import "Course.h" 3 #import "Student.h" 4 5 @interface ViewController () 6 @end 7 8 @implementation ViewController 9 10 ////重寫(xiě)初始化方法,控制器對(duì)象創(chuàng)建結(jié)束后會(huì)執(zhí)行11 //12 //-(id) initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil{13 // 14 // self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];15 // 16 // if(self) {17 // self.students= [NSMutableArray alloc];18 // }19 // 20 // return self;21 //}22 23 - (void)viewDidLoad {24 [super viewDidLoad];25 26 //在頁(yè)面準(zhǔn)備前對(duì)數(shù)組進(jìn)行初始化27 _students = [[NSMutableArray alloc] init];28 29 // _students = [NSMutableArray arrayWithObjects:@"武漢",@"上海",@"北京",@"深圳",@"廣州",@"重慶",@"香港",@"臺(tái)海",@"天津", nil];30 //31 _stuList = [[UITableView alloc] initWithFrame:CGRectMake(0, 250, 520, 420)];32 33 //設(shè)置數(shù)據(jù)源,注意必須實(shí)現(xiàn)對(duì)應(yīng)的UITableViewDataSource協(xié)議34 _stuList.dataSource = self;35 36 //動(dòng)態(tài)添加37 [self.view addSubview:_stuList];38 39 }40 41 - (void)didReceiveMemoryWarning {42 [super didReceiveMemoryWarning];43 }44 45 -(void) onAdd:(UIButton *)btn{46 //這里實(shí)例化一個(gè)Student對(duì)象試試47 //這里如果數(shù)字輸入錯(cuò)誤會(huì)導(dǎo)致解析出問(wèn)題,可能會(huì)報(bào)錯(cuò),不知道OC生產(chǎn)項(xiàng)目應(yīng)該如何處理48 Student *student = [[Student alloc]49 initWithName:_stuName.text50 andAge:[_stuAge.text intValue]51 andSex:_stuSex.text52 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:[_stuChinese.text floatValue]]53 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:[_stuMath.text floatValue]]];54 55 //這里每次點(diǎn)擊,皆將結(jié)果存于全局?jǐn)?shù)組中56 [_students addObject:student];57 58 //每次數(shù)據(jù)更新便將對(duì)應(yīng)數(shù)據(jù)顯示在UITableView中59 [_stuList performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];60 61 }62 63 -(void) onRead:(UIButton *)btn{64 for(id item in _students){65 [item showData];66 }67 }68 69 //必須實(shí)現(xiàn)70 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath71 {72 static NSString *CellWithIdentifier = @"Cell";73 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];74 if (cell == nil) {75 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellWithIdentifier];76 }77 NSUInteger row = [indexPath row];78 cell.textLabel.text = [[_students objectAtIndex:row] getData];79 80 return cell;81 }82 83 //每個(gè)section下cell的個(gè)數(shù)(必須實(shí)現(xiàn))84 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{85 return _students.count;86 }87 88 @end
1 #import "ViewController.h" 2 #import "Course.h" 3 #import "Student.h" 4 5 @interface ViewController () 6 @end 7 8 @implementation ViewController 9 10 ////重寫(xiě)初始化方法,控制器對(duì)象創(chuàng)建結(jié)束后會(huì)執(zhí)行11 //12 //-(id) initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil{13 // 14 // self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];15 // 16 // if(self) {17 // self.students= [NSMutableArray alloc];18 // }19 // 20 // return self;21 //}22 23 - (void)viewDidLoad {24 [super viewDidLoad];25 26 //在頁(yè)面準(zhǔn)備前對(duì)數(shù)組進(jìn)行初始化27 _students = [[NSMutableArray alloc] init];28 29 // _students = [NSMutableArray arrayWithObjects:@"武漢",@"上海",@"北京",@"深圳",@"廣州",@"重慶",@"香港",@"臺(tái)海",@"天津", nil];30 //31 _stuList = [[UITableView alloc] initWithFrame:CGRectMake(0, 250, 520, 420)];32 33 //設(shè)置數(shù)據(jù)源,注意必須實(shí)現(xiàn)對(duì)應(yīng)的UITableViewDataSource協(xié)議34 _stuList.dataSource = self;35 36 //動(dòng)態(tài)添加37 [self.view addSubview:_stuList];38 39 }40 41 - (void)didReceiveMemoryWarning {42 [super didReceiveMemoryWarning];43 }44 45 -(void) onAdd:(UIButton *)btn{46 //這里實(shí)例化一個(gè)Student對(duì)象試試47 //這里如果數(shù)字輸入錯(cuò)誤會(huì)導(dǎo)致解析出問(wèn)題,可能會(huì)報(bào)錯(cuò),不知道OC生產(chǎn)項(xiàng)目應(yīng)該如何處理48 Student *student = [[Student alloc]49 initWithName:_stuName.text50 andAge:[_stuAge.text intValue]51 andSex:_stuSex.text52 andChinese:[[Course alloc] initWithName:@"語(yǔ)文" andScore:[_stuChinese.text floatValue]]53 andMath:[[Course alloc] initWithName:@"數(shù)學(xué)" andScore:[_stuMath.text floatValue]]];54 55 //這里每次點(diǎn)擊,皆將結(jié)果存于全局?jǐn)?shù)組中56 [_students addObject:student];57 58 //每次數(shù)據(jù)更新便將對(duì)應(yīng)數(shù)據(jù)顯示在UITableView中59 [_stuList performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];60 61 }62 63 -(void) onRead:(UIButton *)btn{64 for(id item in _students){65 [item showData];66 }67 }68 69 //必須實(shí)現(xiàn)70 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath71 {72 static NSString *CellWithIdentifier = @"Cell";73 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];74 if (cell == nil) {75 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellWithIdentifier];76 }77 NSUInteger row = [indexPath row];78 cell.textLabel.text = [[_students objectAtIndex:row] getData];79 80 return cell;81 }82 83 //每個(gè)section下cell的個(gè)數(shù)(必須實(shí)現(xiàn))84 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{85 return _students.count;86 }87 88 @end
幾天來(lái),我們?cè)跊](méi)有OC的基礎(chǔ)下搞上面那個(gè)東西出來(lái),一路磕磕碰碰,算是有了一個(gè)開(kāi)始,接下來(lái)的章節(jié),我準(zhǔn)備鞏固下基礎(chǔ)知識(shí),再下周的時(shí)候考慮做一點(diǎn)更加實(shí)際的東西
因?yàn)槲乙彩浅鯇W(xué),文中肯定有很多不足,各位就不要噴了
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注