.net 碼農轉戰 iOS - 初探


好久沒寫博客了,之前還打算把畢業設計中涉及到的兩個算法拿出來說說(臉型分析 + 聲音分析),博文都寫了一半了,后來實在太忙了,那篇隨筆也就沉在草稿列表中沒動過。

我原先是專職 .net 開發的,在公司負責的項目是內部自用的銷售管理系統,由於不需要出去"拋頭露臉",所以公司干脆什么也沒配置(指產品、設計、前端等等,開發設備還是有的),於是所有工作全包了。原本對自身的計划是,后續會慢慢轉產品方面的。

后來,也算是一個契機,公司所有移動端的人基本走光了(iOS 全走了,Android 的好像只剩 2 個!!公司內部的事,這里就不多說了),於是上頭經理就打算讓我們轉到移動端開發。.net 和 java 一直都是"死對頭"(自己的理解,求別噴),所以我不會選 Android,WP 市場還不夠,轉過去對自己競爭力的提升不大,於是乎選擇了 iOS 開發,於是乎便有了這篇《.net 碼農轉戰 iOS - 初探》。。。

 

大學時期有一點 C 的基礎,但是對 OC 完全不知,這次屬於從 0 開始(不選擇 swift 開始,其實是怕它還不夠成熟。語言這東西,其實說到底是相通的,理解了基礎的東西,還怕以后學不會其他的么!)。

我是屬於自學的,看視頻、查資料一步步慢慢走。

http://wenku.baidu.com/course/view/1ce3571252d380eb62946d8c - C + OC 的講解,比較基礎,可以參考(那講師的聲音,我實在頂不住,幾次聽了想摔鍵盤,要不是沒錢買新的。。。)

http://edu.51cto.com/course/course_id-779.html - iOS 各控件的講解,也算基礎,可以參考(中間換了幾個講師,總的來說還是不錯的)

iOS 實戰開發(甘泉) - 屬於實戰型的,挺不錯的(自己下載的視頻,網上不知道有沒在線鏈接)

學習真的需要動手敲鍵盤,單單只是看一下是記不住理解不了的,至少我還沒到那個看看就會的地步。。。

 

· 我從 xcode5 開始,這時候已經少了很多內存管理的代碼了(基本不用寫 release 了),但是不需要你寫,並不代表不需要你了解。所以內存管理需要詳看。

· 命名空間,OC 里是沒有這個概念的。區分兩個不同的類,僅僅是依靠類名。所以一般都會在真正類名前,加一個前綴用來區分,例如 NSString(NS 開頭的代表為 MAC OS X 的核心,即 NeXTSTEP 的縮寫)、CGPoint。。。許多程序員都會使用自己名字的縮寫做類的前綴。

· OC 大量使用指針,而且需顯性表示(NSString *str; str 是一個指針變量,前面需加一個 "*" 顯性體現,表示它是一個指向 "字符串" 的變量)。.net 中也有這個概念,只是不需要顯性表明("*"),參考 .net 中,類、string 的聲明。

· @"",OC 中字符串的寫法,前面必須加一個 "@" 表示是 NSString 類型;

· NSLog() 方法,即 .net 中 Console.WriteLine 方法,支持字符串的 Format,例如 NSLog(@"%@, %i,  %f", @"1", 1, 1.0);(@"%@" 功能很強大,類似於 .net 中 ToString() 方法)。

· 類的聲明,創建一個普通的類,包含一個 .h 文件和一個 .m 文件(例如 SLTest.h & SLTest.m),是成對出現的,.h 文件為頭文件,一般用來做類的聲明,類似 .net 里的抽象類;.m 文件為實現文件,用來實現對應的"抽象類"。

/**
 SLTest.h
 **/
// 使用 import 引入頭文件
// Foundation 為基礎框架
// import 表示該頭文件只被包含一次,無論該命令在整個程序中出現多少次
#import <Foundation/Foundation.h>

// 用 interface 標明是類的聲明
// 該類繼承自 NSObject,類似 .net 里的基類 object
@interface SLTest : NSObject
{
    // 聲明成員變量
}

// 聲明公有方法

@end


/**
 SLTest.m
 **/
// 使用 import 引入頭文件
#import "SLTest.h"

// implementation 標明是類的實現
@implementation SLTest

// 定義、實現私有方法

// 實現公有方法

@end

· OC 中聲明類使用 interface 關鍵字,實現類使用 implementation 關鍵字。其實 OC 中還有一個關鍵字 "class",它並非 "聲明類" 的意思,而是 "包含類" 的意思。功能與 import 相似,但使用 import,編譯時會將 import 的文件整個包含進來,而使用 class,編譯時只是告訴它已經有這個類,而不會整個包含進來,比 import 更輕量級。多用在只需要知道類名,而不需要使用類中方法的地方(例如變量聲明等)。使用方法:@class SLTest;。最大好處,例如有兩個類:A、B,A 中有一個變量 B b;,B 中有一個變量 A a;,如果使用 import,那么編譯時就是"我中有你你中有我",互相包含,最后造成包含的死循環。

· OC 中方法的調用是使用 "[]",例如 [aaa AAA],在 .net 中即表現為 aaa.AAA(); 。有參數的方法調用例如 [aaa BBB:1 CCC:2],在 .net 中表現為 aaa.BBB:CCC:(1, 2); 。注意,OC 中 ":" 也是方法名,有多少個 ":" 表示有多少個參數,而參數的傳入是嵌套在方法名中的(怎么定義怎么用,例如剛才有參數的方法,定義為 -(void)BBB:(NSInteger)i CCC:(NSInteger)j;),這點和 .net 有很大的不同。

· 實例化一個對象,由於要考慮到內存管理問題,OC 中基本都是用 alloc + initXXX 方法(也有個別使用其他工廠模式方法,在此不包括),alloc 表示分配內存,initXXX 表示初始化。基本使用方法:[[NSString alloc] initWithFormat:@"this is a string."]。這里的意思是實例化一個 NSString 對象,指向 "this is a string." 的內存塊(initWithFormat:() 是 NSString 自有方法,其他類型也有類似的 initXXX() 的方法,也有的只有 init() 方法)。當然 OC 也有 new() 方法,但是不建議使用。還是 .net 的 new() 好用!!OC 中沒有重載,只能用方法名來區分。例如 NSString 中的 initWithFormat() 方法和 initWithCoder()。還是 .net 的 new() 好用!!

· get/set 方法,.net 中我們是使用 { get; set; } 讓編譯器自動為我們添加,OC 也有類似的:

// 使用 property 關鍵字聲明
// 括號內指定該屬性的形式:
// nonatomic 表示線程不安全的,在單線程不考慮線程安全的情況,使用 nonatomic 就可以了,對應的 atomic
// 一般基礎類型用 assign,NSString 用 copy,其他用 strong(retain),當然,凡事也有例外,具體自行谷哥吧
// 此外還有 readonly、getter 等等,自行谷哥吧
@property (nonatomic, assign) BOOL balabalabala;

只需要這句話,編譯器會自動生成私有的成員變量和對應的 get/set 方法,當然也可以自己重寫 get/set 方法,在 .m 文件中實現即可。

· 方法前面,"-" 表示是實例方法,即由實例調用;"+" 表示是類方法,即 .net 中類的靜態方法。

· OC 中的 id 類型,弱類型,類似 js 里的 var,硬要跟 .net 掛鈎的話,很像 dynamic,但貌似又跟 dynamic 有所不同,請原諒我蹩腳的表達能力。。。

· self 關鍵字,即 .net 中的 this 關鍵字;super 關鍵字,即 .net 中的 base 關鍵字。

· block,也就是 .net 中的匿名函數,定義順序是:返回類型、"^"關鍵字、方法名(若聲明位置是方法參數,可省略)、參數列表,例如:

// 返回類型為空
// 方法名為 TEST1
// 參數列表為空
void (^TEST1)(void) = ^ {
    NSLog(@"TEST1");
};
TEST1();

// 返回類型為 NSString *
// 方法名為 TEST2
// 需傳入一個 NSInteger 類型的參數
NSString *(^TEST2)(NSInteger) = ^(NSInteger i) {
    NSLog(@"TEST2 parameter: %i", i);
    
    return @"test2";
};
NSString *result = TEST2(10);
NSLog(@"%@", result);

// TEST3 方法定義了一個 block 參數,該 block 無返回值,需傳入一個 NSString 類型的參數
- (void)TEST3:(void (^)(NSString * parameter))block
{
    NSLog(@"TEST3");
    
    // 調用 block,並傳入參數
    block(@"TEST3 parameter");
}
// 調用 TEST3,傳入 block
[self TEST3:^(NSString *parameter)
{
    NSLog(@"parameter: %@", parameter);
}];

用法同 .net 的無異,只是語法不同。

· category,擴展,即 .net 中的類擴展,例如 public static bool IsValidEmailAddress(this string str);。OC 中,只允許擴展方法,寫法:

/**
 NSString+Category.h
 文件命名方法,OC 建議是原類名+擴展名
 **/
// 聲明時,原類名后加一個括號,括號里為擴展名,表示這是一個擴展
@interface NSString (Category)

// 擴展一個方法,判斷該字符串是否為 Email 地址
- (BOOL)isValidEmailAddress;

@end


/**
 NSString+Category.m
 **/
@implementation NSString (Category)

// 實現方法
// 請忽略具體方法,這里只做演示
- (BOOL)isValidEmailAddress
{
    return [self length] % 2 == 0;
}

@end


// 使用時,引入 .h 文件,即可像普通類方法一樣使用
NSString *str1 = @"1";
NSString *str2 = @"11";
NSLog(@"%i", [str1 isValidEmailAddress]);
NSLog(@"%i", [str2 isValidEmailAddress]);

· delegate,協議,注意,這里並不同 .net 中的 delegate,.net 中的 delegate 應該更類似 OC 中的 block。這里的 delegate 更像是 .net 中的接口。用我自己的理解來說,就是我有時候會觸發某個事件,而你如果需要知道我何時觸發了事件,那么我們之間就必須有一種 "約定協議",即當我觸發事件時,通知你。而你收到我的通知后,要干嘛,那是你的自由了。

這里所說的 "約定協議",即 OC 中的 delegate。我要通知你,即使用 delegate 中的方法。你只需要實現這個方法,我就可以通知到你。這個在下一篇再進行詳細說明。

 

OC 的一些基礎的東西就差不多了,接下來就是結合到界面的開發,形式很像 .net 的 winform 開發,iOS 中使用 MVC 框架,所以如果你 .net 會這兩樣的話,還是比較容易看得懂的。

做一款像樣的 App,需要各種崗位的同事幫忙,從需求,到設計、編碼、測試、上線,確實考驗一個團隊的合作能力。

今天好累,洗洗准備睡了。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM