開發手機游戲,需要接入ios的sdk,截止2021年7月23日雖然swift已經推出一些年頭,但對於大部分的渠道sdk,還是oc的代碼。
oc不僅僅用來開發ios,還是mac上的app開發語言
從新手到入門
新手教程
object c的簡寫是objc,很多類都是NS開頭,這是喬布斯離開蘋果后自己創立的NeSt公司的簡寫
基礎知識:.mm是objc++的代碼,.cpp是C++的代碼,.m是objc的代碼,.h是頭文件,只寫接口
objc語言新手教程《Objective-C基礎教程:1天玩轉Objective-C語法》,在1天看完后心里大概有個語言的概念
對objc有一個比較全面的認識之后,可以看這篇《Objective-C 簡介》
在windwos上運行objc,會是比較麻煩的一件事,而且沒有優秀的IDE,不建議
先寫定義,再寫實現,放在兩個文件中,也可以通過xcode新建cocos則會創建出這兩個文件來
xcode編寫objc的感受
在xcode可以新建控制台項目,用來學習objc語言,還是非常合適的。在編寫代碼的過程中,對於代碼中的編譯錯誤,xcode的提示還是很全面並且很及時,但是他沒有像rider那樣按下Alt+Enter就可以修復一些明顯的代碼錯誤。
一些疑問
是不是引用類型,創建出來的實例都要加上*? 比如:
Person *ZhangSan=[[Person alloc] init];//創建一個對象
[ZhangSan displayWithDriveHours:10]; //調用對象的方法,傳入10
Q:為什么C#引用其它的文件,不需要using,而c++和lua,python都需要import?
A:C#是把同一個namespace編譯到一個dll,而lua,python是單個文件,c++還在學習中
Q:id動態類型,是不是從當前文件中查看方法?是從當前類型中去查找方法
Q:NSArray中,初始值是@"1",@"2",但是打印出來卻是整形,直接取值出來也是整形,這點和C#的差別比較大,是怎么實現的?
Q:sdkxxx.framework中有個info.plist,然后sdk的最上層也有一個info.plist,這兩個是和安卓中的manfest一樣,打包時會自動合並?
oc語言checklist
開發工具AppCode,XCode
.h和.m都是以@end結束
類方法+,可以理解為C#中的static,對象方法-就是實例的方法
oc中的發送消息,就是其它語言中的調用方法
oc中對象的初始化(分配內存),[[Class alloc] init],對應C#的new Class()
oc中方法的調用格式[實例對象 方法名],對應C#中的.
oc中方法的調用格式[實例對象 方法名:參數1值 參數1名稱],對應C#中的.
只有一個參數的情況:[ZhangSan displayWithDriveHours:10];
“^”是block代碼塊的標志,可以理解為局部函數,或C#中的Action
+類方法(static),-對象方法(普通方法)
接入sdk時,用到很多的block代碼塊的方式來寫代碼
編譯方式不一樣,C#是編譯到程序集(dll),oc是靜態鏈接庫(需要補充知識)
oc的數據結構
oc中基礎框架的代碼是在Foundation.h中導入了其它頭文件(.h),比如數組,字典,字符串,文件類,日期類,線程類等一系列編程的基礎元件。
NString* str = @"";
BOOL
NSArray 不允許存int ,float ,nil,nil就是結束,那么怎樣存整形數組??
NSMutableArray 可變類型的數組,有增加和刪除方法
NSDictionary 字典,oc中的基礎類型都不能當鍵和值?必須要把它們轉成對象才可以使用,那這樣不科學啊C#中沒有這個限制
字典來看,是先添加value再添加key
NSMutableDictionary可變類型字典
NSNumber類實現的功能是C語言中的基本數據類型和OC對象相互轉換,轉換之后就可以把int放到NSArray中了
用的最多的數據類型
NString,NSDictionary ,NSArray,NSNumber(包裹類,數據類型轉換)
語言特性
通知addObserver:self 添加監聽,可以理解為C#中的Action/event,移除事件removeObserver。從sdk代碼來看 return self這個返回結果不是必須的
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(對象) name:@"事件名?" object:nil]
forKey, valueForKey
KVO:Key-Value-Observer,可以理解為當鍵值發生改變時的事件,這個功能在C#中通過事件系統就可以實現。
NSPredicate 謂詞(過濾器),有點像C#中的Linq用來寫條件篩選數據
plist文件,它的全稱是:Property List。這種文件保存數據的特點就是只能保存:NSString、NSArray、NSData、NSDate、NSDictionary、BOOL、NSNumber這幾種數據類型。
方法創建和調用
文檔:http://c.biancheng.net/cpp/html/3196.html
//類方法的創建:
+(int)personWithA1:(float)a1 andA2:(NSString*)a2; //a1,a2分別代表兩個參數
//對象方法的創建:
-(int)personWithA1:(float)a1 andA2:(NSString*)a2;
//“+”“-”號的不同是區分它們的一個標志,兩種創建類方法不同之處的重點是調用對象的不同:
//調用類方法
[Person personWithA1:2 andA2:@"類方法"];//調用對象是類名
//調用對象方法
Person * obj1=[[Person alloc]init];
[obj1 personWithA1:1 andA2:@"對象方法"];//調用對象是類對象
return 0;
“^”block代碼塊
可以理解為是C#中的Action
普通的函數定義
-(void)displayWithDriveHours:(int)hours{
self.car.driveHours+=hours;
}
^block代碼塊的定義
void (^helloWorld)(void);
helloWorld=^(void){
NSLog(@"Hello World!");
};
helloWorld();
第1行(^helloWorld)這個是代碼塊的聲音,第1行前面的void是返回類型,后面的(void)是參數,如果是int則寫成(int arg1,int arg2)
第2行開始是代碼塊的實現,^必須要有
block實現和定義寫在一起的情況
#import <Foundation/Foundation.h>
int number=10;
int main(int argc, const char * argv[]) {
__block int i=10;
void(^block)()=^{
NSLog(@"The i is :%d",i);
NSLog(@"The number is :%d",number);
i++;
number++;
};
block();
NSLog(@"The i is :%d",i);
NSLog(@"The number is :%d",number);
return 0;
}
接入ios sdk未用到的知識
typedef 用於簡化block代碼塊,未用到
writeToFile:path 文件讀寫,未用到
@protocol 協議,沒有父類,有點像C#的接口,未用到 http://c.biancheng.net/cpp/html/3204.html
類別,未用到,不太像C#中的抽象類,有點像擴展類partical?,它可以只給父類添加方法而不影響子類 http://c.biancheng.net/cpp/html/3203.html
NSUserDefaults 用戶默認設置,可以用來保存用戶登錄的用戶名,查看SDK中不包含這個
內存管理
自動引用計數:ios和mac兩種開發都支持。(Xcode4.2之后才可以使用,簡稱:ARC(Automatic Reference Counting),ARC是Mac OS X 10.7和iOS 5 引入的新的內存管理方式)
他人學習資料
C#中方法調用是靜態的,綁定發生在編譯時 (暫時忽略動態編譯)。Objective-C 消息則在運行時動態綁定對象,而非編譯時。這意味着你可以發送任意定義好的消息給對象,編譯器都不會報錯。錯誤會在運行時拋出
這個需要查看C#的IL代碼,再做評論
unity與ios交互
在unity中函數定義,生成xcode工程時,會生成對應的空方法, 在oc中寫方法的實現,可查看《Unity接入IOS SDK筆記》
開發ios插件文檔:https://docs.unity3d.com/cn/current/Manual/PluginsForIOS.html
oc中調用unity的方法UnitySendMessage(gameobject名字,方法名,參數)