面试题答案
一键面试1. 使用 JSON 进行数据传递
- 常用方式:将数据序列化为 JSON 字符串进行传递。在 Objective - C 中可使用
NSJSONSerialization
类,在 Unity 中可使用JsonUtility
等工具。例如,Objective - C 中把字典转化为 JSON 数据:
NSDictionary *dataDict = @{@"key": @"value"};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dataDict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
在 Unity 中接收 JSON 字符串并转化为对象:
[Serializable]
public class MyData {
public string key;
}
string jsonString = "{\"key\":\"value\"}";
MyData data = JsonUtility.FromJson<MyData>(jsonString);
- 传递复杂数据结构问题:自定义对象需满足特定的序列化规则。如果对象包含复杂的嵌套结构、循环引用或者非基本数据类型成员(如文件句柄等),JSON 序列化可能无法处理。
- 解决方案:对复杂对象进行拆解,确保所有成员都可序列化。例如,避免循环引用,将文件句柄等不可序列化成员转换为可序列化的表示形式(如文件路径)。在 Unity 中,自定义对象需要标记
[Serializable]
特性,并确保所有成员类型可序列化。
2. 使用二进制序列化进行数据传递
- 常用方式:在 Objective - C 中可使用
NSKeyedArchiver
进行归档(二进制序列化),Unity 中可使用BinaryFormatter
(.NET 平台)。比如,Objective - C 中对自定义对象进行归档:
#import <Foundation/Foundation.h>
@interface MyObject : NSObject <NSCoding>
@property (nonatomic, strong) NSString *name;
@end
@implementation MyObject
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
_name = [coder decodeObjectForKey:@"name"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.name forKey:@"name"];
}
@end
MyObject *obj = [[MyObject alloc] init];
obj.name = @"example";
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:obj];
在 Unity 中使用 BinaryFormatter
反序列化(需注意安全性,.NET Framework 中使用):
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class MyUnityObject {
public string name;
}
MemoryStream stream = new MemoryStream(archivedData);
BinaryFormatter formatter = new BinaryFormatter();
MyUnityObject unityObj = (MyUnityObject)formatter.Deserialize(stream);
- 传递复杂数据结构问题:不同平台对二进制格式的兼容性问题。不同语言或运行时环境对二进制序列化的实现细节不同,可能导致反序列化失败。另外,安全问题,如恶意构造的二进制数据可能导致安全漏洞。
- 解决方案:定义统一的二进制格式规范,并进行严格的版本管理。在安全方面,对输入的二进制数据进行严格验证,避免使用不安全的反序列化方法(如在 .NET Core 中已弃用
BinaryFormatter
,可考虑使用更安全的序列化方式,如MessagePack
等)。
3. 使用消息队列(如 RabbitMQ 等类似机制,假设在项目中有此环境)
- 常用方式:Objective - C 和 Unity 都可以连接到消息队列服务器,通过发送和接收消息来传递数据。例如,Objective - C 使用相应的客户端库发送消息:
// 使用 RabbitMQ 客户端库示例代码(实际需安装并配置库)
#import <AMQPClient/AMQP.h>
AMQPConnection *connection = [[AMQPConnection alloc] initWithAddress:@"amqp://server:port"];
AMQPChannel *channel = [connection createChannel];
AMQPQueue *queue = [channel declareQueue];
NSString *message = @"data to send";
[queue publish:message];
在 Unity 中使用相应客户端接收消息(同样需对应客户端库):
// 假设使用 RabbitMQ .NET 客户端
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
ConnectionFactory factory = new ConnectionFactory() { HostName = "server", Port = 5672 };
using (IConnection connection = factory.CreateConnection())
using (IModel channel = connection.CreateModel())
{
string queueName = channel.QueueDeclare().QueueName;
EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
byte[] body = ea.Body.ToArray();
string message = Encoding.UTF8.GetString(body);
};
channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
}
- 传递复杂数据结构问题:消息队列一般传输文本或字节数组,对于复杂数据结构同样需要序列化。并且由于消息队列异步特性,数据接收和处理顺序可能与发送顺序不一致,可能导致复杂数据结构的处理逻辑错误。
- 解决方案:采用可靠的序列化方式(如 JSON 或二进制序列化)将复杂数据结构转化为可传输格式。对于顺序问题,可以在消息中添加序列号等标识,在接收端按序处理。