Unity iOS接SDK前先要了解的知识(Objective-C)
发布日期:2021-06-30 19:35:19 浏览次数:3 分类:技术文章

本文共 5170 字,大约阅读时间需要 17 分钟。

文章目录

一、前言

Unity项目开发,iOS平台要接SDK的话,就需要写Objective-C代码,对于没使用过Objective-C的小伙伴可能会害怕,不要怕,我整理了接SDK需要了解的关键的Objective-C知识。

二、Objective-C代码的文件扩展名:.h、.m和.mm

扩展名 内容类型
.h 头文件。头文件包含类,类型,函数和常数的声明。
.m 源代码文件。这是典型的源代码文件扩展名,可以包含Objective-CC代码。
.mm 源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-CC代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名。

三、#include与#import

当你需要在源代码中包含头文件的时候,你可以使用标准的#include编译选项,但是OC提供了更好的方法:#import

#import选项和#include选项完全相同,只是它可以确保相同的文件只会被包含一次。OC的例子和文档都倾向于使用#import

""和<>的区别

使用""引入的是本地工程的文件,而使用<>引入的是系统库的文件。
在使用中,""会先查找用户目录下文件是否存在,或者说是User Header Search Paths,如果不存在,会继续查找库目录,也就是System Header Search Paths
<>只会查找库目录(System Header Search Paths),如果查找失败,并不会继续查找用户目录。
所以对于不熟练的用户,一般都推荐直接使用""

四、@interface与@implementation

接口(@interface)是类为对象提供特性描述。在@interface中我们可以声明对象的数据成员、属性、以及方法,如下:

@interface AllWeatherRadial {
float rainHandling; float snowHandling;}- (void) setRainHanding: (float) rainHanding;- (float) rainHandling;- (void) setSnowHanding: (float) snowHanding;- (float) snowHandling;@end

@implementation中实现在@interface定义的方法。

注意:在@implementation中,也可以定义@interface本没有的方法以及数据成员,但这个方法就是当前对象的私有方法,无法被子类继承,例:

@implementation AllWeatherRadial- (void) setRainHanding:(float) rh{
rainHandling = rh;}- (float) rainHandling{
return (rainHandling);}- (void) setSnowHanding:(float) sh{
snowHandling = sh;}- (float) snowHandling{
return (snowHandling);}@end

五、方法前的+和-

Objective-C中,方法分为类方法和实例方法两种。

前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的。
前置减号(-)的方法为实例方法,必须使用这个类的实例才可以调用它。

六、创建和初始化对象:alloc、init

Myclass *a = [[Myclass alloc]init];

alloc的作用如其英文含义一样,分配内存给对象,使对象不被释放,将地址返回给指针。

但是分配了内存后,这片内存还没有得到正确的初始化,就跟C中的malloc()函数分配了内存需要调用memset()函数进行初始化一样,OCinit就是为分配好的内存进行初始化。

七、NSString与NSMutableString

Objective-C中核心处理字符串的类是NSStringNSMutableString,这两个类最大的区别就是NSString创建赋值以后该字符串的内容与长度不能在动态的更改,除非重新给这个字符串赋值。而NSMutableString创建赋值以后可以动态在该字符串上更改内容与长度。

//经典的字符串赋值NSString *str0 = @"我是林新发";//字符串格式化合并分别包括//NSString*类型 int类型 char*类型 NSString *str1 = [NSString stringWithFormat:@"我的名字:%@ 我的年龄:%d 我的博客:%s",@"林新发", 25,"https://blog.csdn.net/linxinfa"];//字符串赋值 参数中只可以写一个字符串 和第一种很像NSString *str2 = [NSString stringWithString:@"我是字符串"];//字符串转换为utf-8格式 参数为char*类型NSString *str3 = [NSString stringWithUTF8String:"字符串转换utf-8格式"];//字符串合并int i  = 100;char*c = "linxinfa";NSString *temp = @"我是临时字符串";//在字符串temp的基础继续添加 int i 与 char* c 组成一个新的字符串NSString *str4 = [temp stringByAppendingFormat:@"整型: %d 字符型 :%s",i,c];//在字符串temp的基础继续添加temp 并组成一个新的字符串NSString *str5 = [temp stringByAppendingString:temp]; //字符串输出,输出结果:我是临时字符串我是临时字符串NSLog(@"str5 = %@", str5);

格式化输出格式

%@ 对象%d, %i 整数%u 无符整形%f 浮点/双字%x, %X 二进制整数%o 八进制整数%zu size_t%p 指针%e 浮点/双字 (科学计算)%g 浮点/双字%s C 字符串%.*s Pascal字符串%c 字符%C unichar%lld 64位长整数(long long)%llu 无符64位长整数%Lf 64位双字%e 是实数,用科学计数法计的

八、匿名函数

许多脚本语言都支持lambda表达式和匿名函数。这两个概念经常与闭包性(closure)相关。

Objective-C语言中提供了这两个概念的实现:叫做block
自从Mac OS X 10.6之后,就可以使用block了,其实这样归功于Clang
匿名函数实际上就是一个没有名字或者标示(identifier)的函数。匿名函数只有内容(也可以叫做body),我们可以将其存储在一个变量中,以便之后使用,或者将其当做一个参数传递给另外一个函数使用。
闭包性这个概念是允许一个函数访问其所声明上下文中的变量,甚至是在不同的运行上下文中。
如下为一个block原型

NSString * ( ^ myBlock )( int );

上面的代码是声明了一个block(^)原型,名字就叫做myBlock,携带一个int参数,返回只为NSString类型的指针。

如下为myBlock的定义

myBlock = ^( int number ) {
return [ NSString stringWithFormat: @"Passed number: %i", number ]; };

注意:不要忘记block后面的分号。

定义好block之后,就可以像使用标准函数一样使用它了:

myBlock(5);

九、.a、.framework、.dylib、.tbd

.a、.framework、.dylib、.tbd都是库。

首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。

什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件。另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间。

上面提到库在使用的时候需要LinkLink的方式有两种,静态和动态,于是便产生了静态库动态库

静态库

静态库即静态链接库(Windows下的 .libLinuxMac下的.a)。之所以叫做静态,是因为静态库在编译的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。
静态库的好处很明显,编译完成之后,库文件实际上就没有作用了。目标程序没有外部依赖,直接就可以运行。当然其缺点也很明显,就是会使用目标程序的体积增大。

动态库

动态库即动态链接库(Windows下的 .dllLinux下的 .soMac下的 .dylib/.tbd)。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来。

动态库的优点是,不需要拷贝到目标程序中,不会影响目标程序的体积,而且同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库)。同时,编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。动态库带来的问题主要是,动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境。如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行(Linux下喜闻乐见的lib not found错误)。

iOS Framework

iOS 8之前,iOS平台不支持使用动态 Framework,开发者可以使用的Framework只有苹果自家的 UIKit.Framework,Foundation.Framework等。这种限制可能是出于安全的考虑。换一个角度讲,因为 iOS应用都是运行在沙盒当中,不同的程序之间不能共享代码,同时动态下载代码又是被苹果明令禁止的,没办法发挥出动态库的优势,实际上动态库也就没有存在的必要了。

由于上面提到的限制,开发者想要在iOS平台共享代码,唯一的选择就是打包成静态库.a文件,同时附上.h头文件。但是这样的打包方式不够方便,使用时也比较麻烦,大家还是希望共享代码都能能像Framework一样,直接扔到工程里就可以用。于是人们想出了各种奇技淫巧去让 Xcode BuildiOS可以使用的Framework,具体做法参考这里和这里,这种方法产生的Framework还有 “伪”(Fake) Framework和 “真”(Real) Framework的区别。

iOS 8/Xcode 6推出之后,iOS平台添加了动态库的支持,同时Xcode 6也原生自带了 Framework支持(动态和静态都可以),上面提到的的奇技淫巧也就没有必要了(新的做法参考这里)。为什么iOS 8要添加动态库的支持?唯一的理由大概就是Extension的出现。ExtensionApp是两个分开的可执行文件,同时需要共享代码,这种情况下动态库的支持就是必不可少的了。但是这种动态 Framework和系统的 UIKit.Framework还是有很大区别。系统的Framework不需要拷贝到目标程序中,我们自己做出来的Framework哪怕是动态的,最后也还是要拷贝到 App中(AppExtensionBundle是共享的),因此苹果又把这种Framework称为 Embedded Framework

使用静态库的好处:

1,模块化,分工合作
2,避免少量改动经常导致大量的重复编译连接
3,也可以重用,注意不是共享使用

动态库使用有如下好处:

1,使用动态库,可以将最终可执行文件体积缩小
2,使用动态库,多个应用程序共享内存中得同一份库文件,节省资源
3,使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。

查看库文件的符号表

比如查看xxxx.a这个库文件的符号表

nm xxxx.a

转载地址:https://linxinfa.blog.csdn.net/article/details/107375140 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:python遇到了‘module‘ object has no attribute ‘socket‘问题,大概率是这个原因
下一篇:Unity iOS接SDK,定制UnityAppController

发表评论

最新留言

不错!
[***.144.177.141]2024年04月07日 22时26分13秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章