在对Swift 3进行更新后,getUUIDBytes
对象上无法显示getBytes
和UUID
。
let uuid = UIDevice.current.identifierForVendor
let mutableUUIDData = NSMutableData(length:16)
uuid.getBytes(UnsafeMutablePointer(mutableUUIDData!.mutableBytes))
// ^^^ compiler error, value of type UUID? has no member getBytes
即使在文档中将getBytes
列为UUID上的方法,我也会收到此错误:https://developer.apple.com/reference/foundation/nsuuid/1411420-getbytes
答案 0 :(得分:3)
一种正确的方式:
let uuid = UIDevice.current.identifierForVendor!
var rawUuid = uuid.uuid
withUnsafePointer(to: &rawUuid) {rawUuidPtr in //<- `rawUuidPtr` is of type `UnsafePointer<uuid_t>`.
rawUuidPtr.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<uuid_t>.size) {bytes in
//Use `bytes` only in this closure. (Do NEVER export `bytes` out of the closure.)
print(bytes[0],bytes[1])
//...
}
}
另一种正确的方式:
withUnsafePointer(to: &rawUuid) {rawUuidPtr in //<- `rawUuidPtr` is of type `UnsafePointer<uuid_t>`.
let bytes = UnsafeRawPointer(rawUuidPtr).assumingMemoryBound(to: UInt8.self)
//Use `bytes` only in this closure. (Do NEVER export `bytes` out of the closure.)
print(bytes[0],bytes[1])
//...
}
正如Rob已经评论过的那样,导出传递给withUnsafeBytes
的闭包参数的指针完全无法保证。稍微改变一下上下文(32位/ 64位,x86 / ARM,调试/发布,添加看似无关的代码......)会让你的应用程序变得更糟糕。
另一个重要的事情是Data
的UTF-8 uuidString
和NSUUID.getBytes
的字节序列完全不同:
let nsUuid = uuid as NSUUID //<-Using the same `UUID`
let mutableUUIDData = NSMutableData(length:16)!
nsUuid.getBytes(mutableUUIDData.mutableBytes.assumingMemoryBound(to: UInt8.self))
print(mutableUUIDData) //-><1682ed24 09224178 a279b44b 5a4944f4>
let uuidData = uuid.uuidString.data(using: .utf8)!
print(uuidData as NSData) //-><31363832 45443234 2d303932 322d3431 37382d41 3237392d 42343442 35413439 34344634>
答案 1 :(得分:3)
你的想法太复杂了:
client.UsingCommands(input => {
input.PrefixChar = '!';
input.AllowMentionPrefix = true;
});
command = client.GetService<CommandService>();
command.CreateCommand("echo").Parameter("param", ParameterType.Multiple).Do(async (e) => {
var channel = e.Server.FindChannels(e.Message.Channel.Name, ChannelType.Text).FirstOrDefault();
string msg = "";
for (int i = 0; i < e.Args.Length; i++) {
msg += e.Args[i] + " ";
}
msg = msg.Remove(msg.Length - 1);
await channel.SendMessage(msg);
});
为什么这样做?
考虑一下:
func getUUID ( ) -> Data {
let uuid = NSUUID()
var bytes = [UInt8](repeating: 0, count: 16)
uuid.getBytes(&bytes)
return Data(bytes: bytes)
}
然后你可以这样做:
func printInt(atAddress p: UnsafeMutablePointer<Int>) {
print(p.pointee)
}
但你也可以这样做:
var value: Int = 23
printInt(atAddress: &value)
// Prints "23"
这是一种隐含的桥接&#34;形式。引用Swiftdoc.org:
隐式创建指向数组元素的可变指针 当您使用inout语法传递数组时。
此隐式桥接仅保证有效指针,直到当前函数返回。这样的指针绝对不能逃脱&#34;当前函数上下文,但使用它们作为inout参数总是安全的,因为inout参数始终只保证在被调用函数返回之前有效,并且被调用函数必须在当前参数之前返回,所以这不会出错。 / p>
对于那些不了解的人,将var numbers = [5, 10, 15, 20]
printInt(atAddress: &numbers)
// Prints "5"
投放到UUID
(NSUUID
),反过来(... as NSUUID
)保证永远成功。但如果你坚持使用... as UUID
,最简单的方法是:
UUID