Unity与iOS交互(1)——需要了解的IOS相关知识

news2024/10/7 7:26:00

【前言】

以下只是简要介绍,详细的内容需要自己去看链接

 【Objective-C基础知识】

.h .m .mm .cpp文件区别

.h是头文件扩展名。头文件包含类,类型,函数和常数的声明,这里的定义一般是Public的

.m是实现文件扩展名。其包含源代码,用于.h文件中的实现,一般是private的。这是C++中的类似。

.mm类似.m,除了可以包含Objective-C代码外,还可以包含C、C++代码

.cpp只能包含C++代码

一般在unity中会使用.h和.mm文件

include和import

两者都可以用于导入需要的源代码的头文件,include与C++中的类似,Import在此基础上会确保相同的文件只会被包含一次,类似Java的import,推荐使用import

""和<>

和C++类型,“”用于导入自定义的文件,<>用于导入系统文件

+和-

+类似C#的静态方法,-类似C#的实例方法

语法基础

Swift和OC

Swift是2014年苹果推出的新语言,相对于OC有很多优势,会逐步取代OC。作为Unity程序,Swift比OC可读性更好,在调用iOS原生功能时,如果用OC不好实现,可以考虑用Swift来写,这时需要了解OC如何调用Swift

【C#与OC的调用】

C#不可以直接调用OC,但可以通过DllImport来调用C,让C调用OC

OC调用C

第一种方式是单独的C头文件,C实现文件

//test.h
#ifndef test_h
#define test_h

#include <stdio.h>

#endif /* test_h */

int Add();


//test.c
#include "test.h"

int Add(int a,int b)
{
    return a+b
}

然后创建OC的头文件,实现文件

//TestOc.h
#import <Foundation/Foundation.h>


@interface TestOC : NSObject

- (int)ocCallC:(int)a with:(int)b;

@end


//TestOC.m
#import "TestOC.h"
#include "test.h" //要include C的头文件

@implementation TestOC

- (void)ocCallC:(int)a with:(int)b
{
    int result = add(a,b);//可以直接按照C语言的函数调用语法来调用函数
    return result;
}

@end

第二种方式是直接在.mm文件中写C函数

//TestOC.mm
#import "TestOC.h"


int Add(int a,int b)
{
    return a+b
}

@implementation TestOC

- (int)ocCallC:(int)a with:(int)b
{
    int result = add(a,b);//可以直接按照C语言的函数调用语法来调用函数
    return result;
}

@end

我们一般不会用第一种方式,还要写C的头文件和实现文件比较麻烦,一般都用第二种方式。

C调用OC

函数调用主要是找到函数的地址,C函数调用直接通过函数名(参数)找到函数指针,直接执行函数地址。OC等面向对象的语言需要通过找到类的地址,然后再找到函数地址。因此,C调用OC函数时,可以直接在C函数中按照OC写法即可。这同样有两种方式,我们直接用第二种方式。

//TestOC.mm
#import "TestOC.h"


int Add(int a,int b)
{
    return a+b
}

@implementation TestOC

+ (void)CCalloc:(int)a with:(int)b
{
    return a + b;
}

int CAdd(int a,int b)
{
  return [TestOC CCalloc:a with:b];
}

@end

extern "C"

extern "C"会指示编译器这部分代码按C语言的方式进行编译,extern表示该代码可以被跨模块使用,编译器在编译时会跨模块寻找而不是在Include的文件中寻找,将找到的函数链接。这样用C#的P/Invoke功能可以调用.mm文件中的函数。代码如下:

//.mm文件中
#if defined(__cplusplus)
extern "C"
{
#endif

    void SDKInit()//按照C的写法
{
    NSLog(@"hello world!");//按照OC的写法
}

//写其他各种代码

    void SDKClose()
{
}

#if defined(__cplusplus)
}
#endif


//C#代码调用
[DllImport("__Internal")]
private static extern void SDKInit();

C调用C#

和Android一样,用UnitySendMessage将消息传递会C#

【Xcode工程基本概念】

workspace、project、target、scheme

  • target是工程中 最小可编译单元,其包含编译时所需要的全部信息,每个target可以被编译成链接库、可执行单元或资源包,类似Android中的library。每次构建应用时,必须指定一个target。target之间可以相互依赖,共享代码和资源,但只有一个能处于Active状态。
  • project就是一个xcode工程,其包含了所有的代码文件、资源文件、framework、基本信息、编译配置等。project是管理资源的容器,其中可以有多个target,其也有基本信息和编译配置,可以用于target,如果target有自己的编译配置等,会覆盖project的。一般情况下工程里只有一个project,双击后缀名为.xcodeproj 的文件即可打开该 project 了。unity xcode project属于一般情况。
  • workspace是对project的进一步分类,其可以对多个project进行管理,因为会存在一个project引用(依赖)另一个project的情况。
  • scheme是编译任务,其定义了编译 target 时使用的配置选项,执行的任务,环境参数等,有预设的六种:Build, Run, Test, Profile, Analyze, Archive

framework

framework类似库,由二进制文件、头文件、资源文件、其他信息等组成。iOS中framework分为系统级别的dynamic framework和用户级别的static framework、embedded framework

.app .xarchive 和 .ipa的区别

.xarchive是对target进行分析、编译和打包后生成的归档文件的文件格式,其中包含了已经编译好的、打包好的二进制代码、资源文件、配置文件等。具体来说是:BCSymbolMaps、dSYMs(解析崩溃堆栈的符号表)、Products(包含表示生成的.app包)、info.plist等。

.ipa(iOS App Store Package)是一个zip压缩包,从应用商店下载就是这个文件,其包含了运行 App 所必需的的签名、二进制包、资源等内容。

.app是程序运行包,其中包括二进制的可执行文件、运行所需要的资源文件、配置文件,签名文件和privisioning file。

.app 文件是在应用程序开发阶段生成的文件,通常用于在模拟器上测试应用程序或在开发阶段进行本地部署

Info.plist

属性列表文件(information property list file)提供应用在运行期的配置,是一个XML文件,类似AndroidManifest.xml,xcode工程会自动创建一个Info.plist,并且提供许多合适的Keys以及其对应的默认的values,例如权限配置等。

【Unity Xcode工程结构】

根据需要在Unity中设置Bundle Identifier等,每个Unity Xcode工程都有如下的结构和targets

  •  Unity-iPhone:这个target包括MainApp文件夹和应用程序表示数据,例如启动屏幕、.xib文件、图标、数据和/Info.plist文件,其依赖于UnityFrameWork target。(Project的名字也是Unity-iPhone)
  • UnityFramework: 这个target包括Classes、UnityFramework和Libraries文件夹,以及相关的框架,Xcode使用它来构建UnityFramework.framework文件

  • GameAssembly:这个target是将C#代码编译为C++代码的容器,Xcode使用Unity在每个生成的Xcode项目中包含的IL2CPP工具实现编译,生成的结果包括:包含项目的所有托管代码并被编译成C++代码的库libGameAssembly.a、包含 IL2CPP 运行时代码以支持项目的托管代码的静态库il2cpp.a。

  • MainApp文件夹:包含程序入口代码文件和可能的资源文件等。

  • Classes文件夹:包含用于集成 Unity Runtime 和 Objective-C 的代码。Unity 将应用程序的入口点存储在此文件夹内的 main.mm 和 UnityAppController.mm/h 文件中。如果你的任何插件包含 AppController.h,你可以改为包含 UnityAppController.h。如果 Plugins/iOS文件夹包含 AppController.mm/h,可以对它们进行合并和重命名。这个文件夹的代码基本不会变化。

  • Data文件夹:包含应用程序的序列化资源以及 .NET 程序集(.dll 或 .dat 文件),其形式为完整代码或元数据(取决于代码剥离设置)。machine.config 文件可以设置各种 .NET 服务(例如安全性和 WebRequest)。Xcode 在每次构建时都会刷新此文件夹的内容。

  • Libraries文件夹:Libraries 文件夹包含用于 IL2CPP 的 libil2cpp.a。libiPhone-lib.a 文件是 Unity Runtime 静态库,RegisterMonoModules.cpp将 Unity 原生代码与 .NET 绑定。Xcode 在每次构建时都会刷新此文件夹的内容。你可以不用做任何修改。Unity工程中的Plugins文件夹里的文件位于该文件夹内。

  • 图形文件:图标和启动画面(.png 文件)位于 Unity-iPhone 文件夹中的资源目录中。Unity 自动管理这些文件。启动屏幕、它们的 XML 接口构建器(.xib 文件)和 Storyboard 文件存储在项目的根文件夹中。

  • FrameWorks文件夹:包含使用的iOS系统framework和第三方framework

【iOS的生命周期】

UIApplication

每一个 iOS app 都会有一个UIApplication的实例,当一个app启动的时候,系统会调用 UIApplicationMain 函数,该函数会创建一个单例UIApplication对象和一个UIApplicationDelegate对象,UIApplication类中会持有一个UIApplicationDelegate,会通知其运行时的一些重要事件,例如app启动、内存过低、状态改变等,我们一般会写一个类继承UIApplicationDelegate来接收通知,自定义处理事件。

iOS是继承C语言的,入口也是main函数,一般在Xcode工程中是固定写好的,不用修改。

#import "AppDelegate.h"

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

APP的五种状态 

Not running(未运行状态):app未启动或者被终止(无论是被系统还是用户)。

Inactive(不活跃状态):app在前台运行但未接收事件。app只在转换到不同状态时会短暂地保持此状态。进入此状态后,app会很快进入后台(Background)或活动(Active)状态。(打电话时或者下拉通知栏时app会进入此状态)

Active(活动状态):app在前台运行并且正在接收事件。处于前台的app通常状态就是Active。

Background(后台状态):app在屏幕上不可见但是正在执行代码,这是后台状态。当用户退出应用后(应该是按home键),系统会将app在挂起(suspend)前短暂地移动到后台(Background)状态。

Suspended(挂起状态):应用程序在内存中,但不执行代码。系统会挂起在后台(Background)状态的应用程序。系统可能会为了腾出内存空间,将app清除出内存。

(类似进程的五种状态:创建状态、就绪状态、运行状态、阻塞状态、终止状态)

 状态转换时的调用

//启动程序是最先调用的函数
-(BOOL) application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    return YES;
}
//在app显示给用户之前,最后的初始化操作。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

/*通知APP将要变成前台程序,这里可以重启被暂停的任务,如果此程序在后台进入可以选择更新用户界面。
 */
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // 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.
}

/**
 * 通知 APP 将进入前台,
 *这里可以撤销一些在为后台运行而做的改变。
 **/

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


/**通知APP将要离开前台,(依次进行inActive -》background-》-Suspended)。如果有电话接入、SMS消息、是用户退出、或者想后台切换都会调用此函数。
 *应该使用这个方法暂停正在执行的任务,取消定时器、取消图形渲染回调,暂停游戏等操作。
 */
- (void)applicationWillResignActive:(UIApplication *)application {
    // 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.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
/**
 *通知APP将要进入后台状态,随时可能被挂起。
 *应该使用这个方法:释放分享的资源,存储用户数据、取消定时器、保存APP的状态消息以用于恢复。
 *如果APP支持后台运行,当用户退回时,调用此方法而不调用applicationWillTerminate。
 **/

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // 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.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

/**
*通知 APP 将要终止,如果程序被挂起将不调用。
*保存数据
**/
- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

UIView和UIWindow

iOS应用程序通过UIView和UIWindow在屏幕上展现图形内容。UIWindow 继承于UIView,但是一个特殊的UIView,其是所有其他UIView的根视图,管理协调应用程序的显示。一般应用程序只有一个UIWindow对象,即使有多个UIWindow对象,也只有一个UIWindow可以接受到用户的触屏事件。Unity会自己渲染画面,不会用iOSUIView,但作为iOS上的应用程序,还是会用到UIWindow

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/726868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云环境利用工具-----cf

简介 CF 是一个云环境利用框架&#xff0c;适用于在红队场景中对云上内网进行横向、SRC 场景中对 Access Key 即访问凭证的影响程度进行判定、企业场景中对自己的云上资产进行自检等等。 项目地址&#xff1a;https://github.com/teamssix/cf 使用手册&#xff1a;https://wi…

Java POI excel单元格背景色(填充)、字体颜色(对齐)、边框(颜色)、行高、列宽设置

文章目录 1、Excel Cell单元格背景色颜色名称对照关系2、Excel Cell单元格背景填充样式颜色填充对照关系3、Excel Cell字体样式设置对照图4、Excel 行高、列宽设置5、Excel单元格边框设置边框类型图片对比附一&#xff1a;一些问题1、关于列宽使用磅*20的计算方式2、关于行高使…

常用数据预处理与特征选择方法总结记录

在很多机器学习或者是深度学习建模之前&#xff0c;对于数据的处理尤为重要&#xff0c;选择合适的数据预处理方法和特征构建算法对于后续模型的结果有着很大的影响作用&#xff0c;这里的主要目的就是想记录总结汇总常用到的处理方法&#xff0c;学习备忘&#xff01; 数据清洗…

Docker集群部署-MySQL主从复制

实验目的 利用Docker实现MySQL主从复制架构的部署&#xff0c;实现1主1从集群配置。 实验准备 要求实验主机能够连接外网&#xff0c;已经正确安装Docker&#xff0c;并关闭防火墙和selinux。 【实验步骤】 新建主服务器容器实例3307 # docker run -p 3307:3306 --name my…

mysql —案例复杂查询+索引使用+DBeaver中创建索引

前言 接上章 我们 对一个简单的选课功能进行 设计分析 实际上在工作中 拿到一个需求&#xff0c;也是这样的一个分析过程 一个份 需求文档原型 出来&#xff0c;只要是你负责这个模块&#xff0c;就需要你自己建表建库&#xff0c;设计接口文档&#xff0c;也许现在有的公司…

AIGC|FineTune工程之LoRa高效参数微调

徐辉 | 后端开发工程师 一、引言 随着深度学习和自然语言处理技术的快速发展&#xff0c;大型预训练语言模型&#xff08;如GPT、Vicuna、Alpaca、Llama、ChatGLM等&#xff09;在各种应用场景中取得了显著的成果。然而&#xff0c;从零开始训练这些模型需要大量的计算资源和…

Cristiano Linux学习小结

一、linux基础 1.1 基本概述 1、Linux组成&#xff1a;内核 Shell 文件系统 应用程序 2、内核&#xff08;Kernel&#xff09;&#xff0c;即核心程序。实现操作系统的基本功能(进程管理、内存管理、进程间通信、虚拟文件系统和网络接口)&#xff0c;决定着系统的性能和稳定性。…

递归典型例题:汉诺塔问题

文章目录 1. 什么是汉诺塔2. 汉诺塔的解题步骤3. 代码实现汉诺塔 1. 什么是汉诺塔 1. 汉诺塔的来源 一位法国数学家曾编写过一个印度的古老传说&#xff1a;在世界中心拿勒斯的圣庙里边&#xff0c;有一块黄铜板&#xff0c;上边插着三根宝柱。印度教的主神梵天在创造世界的时…

div绑定键盘点击事件

为箭头绑定绑定键盘方向键 <div class"toggle-nav"><spanv-if"leftToggleSt"click"toggleGoods(1)"keyup.left"toggleGoods(1)"class"toggle-left"><a-icon type"left" class"icon" /&…

Linux系统设置

Linux的系统设置 01 选择“Install CentOS7” 02 选择安装界面的语言 03 选择时区&#xff0c;这里选择上海 04 选择安装类型&#xff0c;选择最小安装即可&#xff0c;不需要图形界面与其他的组件 05 选择安装位置&#xff0c;自定义分区 06 我要配置分区&#xff0c;进行…

ARS408毫米波雷达使用记录

参考&#xff1a;ARS_408毫米波雷达数据解析学习记录 感谢博主的分享&#xff08;https://blog.csdn.net/weixin_49401384&#xff09; 雷达can消息解析&#xff08;通用can解析思路&#xff09; socketcan学习can总线 毫米波雷达can协议解读RadarCfgRadarState 代码基本是关于…

Python接口自动化核心模块 - 数据库操作和日志

进行接口测试时&#xff0c;我们需要连接到数据库中&#xff0c;对数据源进行备份、还原、验证等操作。 Python连接数据库常见模块 MysqlDB python2时代最火的驱动库。基于C开发&#xff0c;对windows平台不友好。现在已经进入python3时代&#xff0c;基本不再使用 MysqlCl…

干农活太累了,尤其是对一位22女孩来说

干农活太累了&#xff0c;尤其是对一位22女孩来说。要是能够通过电商来销售农产品可以大大减轻干农活的负担。在重庆荣昌的一个小村庄里&#xff0c;一个名叫杨儿杨的00后女孩&#xff0c;正通过抖音电商&#xff0c;书写着她自己的故事。杨儿杨的生活并不容易。5岁前&#xff…

数据库 --- mysql(01)

MYSQL 1、数据库简介 数据&#xff1a;描述事物的符号记录&#xff0c; 可以是数字、 文字、图形、图像、声音、语言等&#xff0c;数据有多种形式&#xff0c;它们都可以经过数字化后存入计算机。 数据库&#xff1a;存储数据的仓库&#xff0c;是长期存放在计算机内、有组…

武大+上交提出 BatGPT:创新性采用双向自回归架构,可预测前后token

进NLP群—>加入NLP交流群 本论文介绍了一种名为BATGPT的大规模语言模型&#xff0c;由武汉大学和上海交通大学联合开发和训练。 该模型采用双向自回归架构&#xff0c;通过创新的参数扩展方法和强化学习方法来提高模型的对齐性能&#xff0c;从而更有效地捕捉自然语言的复杂…

Seata 分布式事务的中间件Seata设计和实现方案

文章目录 分布式事务的中间件SeataSeata AT 模式-默认模式前提整体机制写隔离读隔离 Seata XA 模式前提整体机制工作机制 Seata TCC 模式Seata Saga 模式概述缺点&#xff1a; Saga的实现外传 分布式事务的中间件Seata Seata 是一款开源的分布式事务解决方案&#xff0c;致力于…

element ui组件的自定义类名样式不生效

element ui中&#xff0c;类似描述列表这种组件 会提供自定义类名属性 需要注意&#xff0c;样式不能写在<style scoped>标签中&#xff0c;会被vue自动加上data-v属性&#xff0c;导致样式失效。 必须写在<style>标签里

C++进阶—红黑树详解及map、set封装(3)

目录 1. 红黑树的概念 2. 红黑树的性质 3. 红黑树节点的定义 4. 红黑树性质分析 5. 红黑树插入节点简要分析&#xff08;新插入节点的parent为红色&#xff09; 5.1 简要分析1-变色&#xff1a; 5.2 简要分析2-变色旋转 5.3 简要分析总结 6. 红黑树插入节点详细分析 …

Linux下载安装Redis(Ubuntu系统)

相比于 Windows 系统而言&#xff0c;Redis 更适合于在 Linux 系统上使用&#xff0c;这是由 Redis 的底层机制决定的。下面介绍一下如何在 Linux 发行版 Ubuntu 系统上安装 Redis 数据库。 了解Redis版本 Redis 版本号采用国际标准惯例&#xff0c;即“主版本号.副版本号.补…

Linux分布式应用 Zabbix监控软件 安装

zabbix 是什么&#xff1f; ●zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 ●zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 ●…