+ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;

NSValue的valueWithBytes:objCType:方法将参数value指针指向的内容存储到新创建的NSValue对象中,而指针指向的内容类型由type参数指定。比如下面的例子:

char *myCString = "";
NSValue *theValue = [NSValue valueWithBytes:myCString objCType:@encode(char *)]; char buffer[1] = {};
[theValue getValue:buffer];
NSLog(@"%s", buffer);

上面代码输出:12345678,而不是123456789。

原因是valueWithBytes:objCType方法保存的是myCString指向的内容(即字符串"123456789"),并且将这个内容当成一个char *指针,而一个指针只有8个字节(具体大小可能因机器而异),所以theValue只能保存字符串的前8个字节,因此,使用NSValue的getValue:方法取出的内容是12345678,而不是123456789。具体流程如下图所示:

要解决这个问题,可以向valueWithBytes:objCType传递myCString变量本身的地址,如下面代码所示:

char *myCString = "";
NSValue *theValue = [NSValue valueWithBytes:&myCString objCType:@encode(char *)]; char *buffer = NULL;
[theValue getValue:&buffer];
NSLog(@"%s", buffer);

这时输出的内容就是:123456789。

上面的代码中,在调用valueWithBytes:objCType之前,各个指针变量指向的值如下图所示:

在上面的图中,变量名上方的数字表示该指针变量存储的地址值,比如,myCString指向字符串123456789,这个字符串的首地址是11111111,buffer变量指向NULL。

调用vaueWithBytes:objCType之后,由于向valueWithBytes:objCType传递的是myCString变量本身的地址&myCString,那么theValue就保存这个地址所指向的内容,即myCString变量保存的地址值11111111,并把这个值当成char *看待。当将buffer变量本身的地址传递给NSValue的getValue方法时,getValue方法将theValue保存的值copy给&buffer指向的缓存区,即copy给buffer变量,因此,buffer变量保存的值就成了11111111,这个值就是字符串123456789的地址,buffer变量就指向了这个字符串。具体流程如下图所示:

还需要主意的是,上面代码传递给valueWithBytes:objCType方法的type参数不一定非要是char *,只要是指针类型就可以,因为指针的大小在同一台机器上是固定的。

参考资料

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/NumbersandValues/Articles/Values.html#//apple_ref/doc/uid/20000174-BAJJHDEG

https://developer.apple.com/reference/foundation/nsvalue/1551466-valuewithbytes?language=objc

NSValue的valueWithBytes:objCType:方法的更多相关文章

  1. Runtime之成员变量&属性&关联对象

    上篇介绍了Runtime类和对象的相关知识点,在4.5和4.6小节,也介绍了成员变量和属性的一些方法应用.本篇将讨论实现细节的相关内容. 在讨论之前,我们先来介绍一个很冷僻但又很有用的一个关键字:@e ...

  2. OC基础(25)

    NSNumber NSValue NSDate NSFileManager *:first-child { margin-top: 0 !important; } body > *:last-c ...

  3. Foudation框架之一些常用结构体和常用类

    表示范围作用的结构体:NSRange:       有三种方式创建新的NSRange: 1.NSRange range:            range.location = 17;         ...

  4. 【IOS】IOS高速入门之OC语法

    Objective-C 是 C 语言的超集 您还能够訪问标准 C 库例程,比如在stdlib.h和stdio.h中声明的那些例程. Objective-C 还是一种很动态的程序设计语言,并且这样的动态 ...

  5. OC-基础数据类型

    七 字符串与基本数据类型转换 获取字符串的每个字符/字符串和其他数据类型转换 八 NSMutableString 基本概念/常用方法 九 NSArray NSArray基本概念/创建方式/注意事项/常 ...

  6. Objective-C中@encode的使用

    今天看Mansonry的代码时,碰到一个生僻的关键字(也许只是自己没用过).:-) @encode  => 将给定类型编码为内部表示的字符串. 为了方便自己查阅,顺便也写个小例子,贴在这里,实践 ...

  7. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  8. Objective-C( Foundation框架 一 NSNumber(NSValue))

    NSNumber: 是OC中处理数字的一个类 NSValue是NSNumber的子类 如何处理: 把int,float,double  包装成一个对象 使用NSNumber的好处: 可以把基本数据类型 ...

  9. NSDate,NSNumber,NSValue

    NSDate #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleas ...

随机推荐

  1. mysql 支持四字节设置

    设置文件mysql/bin/my.ini[mac用户在ect文件夹里创建文件my.cnf] 添加以下代码: [mysqld] character-set-server=utf8mb4

  2. 正则表达式-Regular expression学习笔记

    正则表达式 正则表达式(Regular expression)是一种符号表示法,被用来识别文本模式. 最近在学习正则表达式,今天整理一下其中的一些知识点 grep - 打印匹配行 grep 是个很强大 ...

  3. angular2或angular4中使用ckplayer播放rtmp和m3u8视频直播流

    1. 下载ckpalyer整个包并导入, 将ckplayer放到src/assets/下 2. 引入ckplayer.js angular2中,在angular-cli.json中找到script,添 ...

  4. 自定义注解实现(spring aop)

    1.基本概念 1.1 aop 即面向切面编程,优点是耦合性低,能使业务处理和切面处理分开开发,扩展和修改方面,当引入了注解方式时,使用起来更加方便. 1.2 应用场景 打日志.分析代码执行时间.权限控 ...

  5. day30 进程

    推荐两本书:现代操作系统和操作系统原来,学习好python以后再去研究.   并发:任务的切换,保存状态,存在io的是实现空间和时间的 重复利用 操作系统的发展历史: 第一代(1940-1955)手工 ...

  6. Facebook 被指收集用户数据:通过照片和文本

    北京时间5月25日消息,在加利福尼亚州进行的对Facebook泄露用户信息一案中,法院对Facebook提起一项新的诉讼,指控该公司通过App收集了用户及他们朋友的信息. 上周向加利福尼亚州圣马特奥市 ...

  7. mac+win10:UEFI分区方式下安装windows 10

    小编,最近通过在远景论坛上寻找教程--安装双系统(win10+mac os).经过一天努力,成功安装win10.为此,特地分享给各位正在需求教程的朋友,我在UEFI分区方式下安装windows 10的 ...

  8. androd hook acitivity 启动流程,替换启动的activity(Android Instrumentation)

    前言:如果程序想要知道有activity启动,如果想要拦截activity,然后跳转到指定的activity怎么办? 我们看下ActivityThread 里面: private Activity p ...

  9. Intellij打包jar文件,“java.lang.SecurityException: Invalid signature file digest for Manifest main attrib

    下面是使用Intellij 打包jar文件的步骤,之后会有运行jar文件时遇到的错误. 打包完成. ================================================== ...

  10. CakePHP Model中( 获取Session)使用Component的方法

    有时候我们需要在Model中使用Session,大家知道CakePHP把操作Session的方法封装为了一个Component, 在Model中正常读取Session的方法: 在 "app_ ...