为游戏接入ios sdk的oc学习笔记


开发手机游戏,需要接入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 
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 引入的新的内存管理方式)


他人学习资料

Somya Jain 谈从 C#到 Object-C

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名字,方法名,参数)