- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章IOS开发中使用writeToFile时的注意事项由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
总会有一些坑在前面等着你 。
我们先来看一下后台返回的部分json数据,稍后再来分析问题,仔细看一下userId和userCode两个字段,其他不用看 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
"list"
: [{
"classId"
:
5000285
,
"className"
:
"考勤(A)班"
,
"schoolId"
:
50011
,
"schoolName"
:
"星星局测中学25"
,
"classLeaderUserId"
:
2000163
,
"parentList"
: [{
"userId"
:
2000790
,
"userName"
:
"zhaomin"
,
"gender"
:
"0"
,
"mobile"
:
"15071362222"
,
"email"
:
""
,
"areaCode"
:
"440105"
,
"avatarUrl"
:
""
,
"userCode"
:
"2000790"
,
"id"
:
1542
,
"roleType"
:
2
,
"nickName"
:
"zhaomin"
}, {
"userId"
:
2000846
,
"userName"
:
"刘玄德"
,
"gender"
:
"1"
,
"mobile"
:
"18825113388"
,
"email"
:
""
,
"areaCode"
:
"440105"
,
"avatarUrl"
:
""
,
"userCode"
:
"2000846"
,
"id"
:
1631
,
"roleType"
:
2
,
"nickName"
:
"刘玄德"
}],
|
问题背景 。
这个问题是在我集成环信IM的时候,由于需要处理用户头像和昵称问题,所以会将联系人的头像url和用户昵称做一个本地缓存,缓存的方式就是采用简单的写入plist文件来处理.之所以使用plist,是因为简单方便,而且可以满足开发,所以就没有采用其他的缓存方式. 。
问题就是出现在写入plist文件上面. 。
遇到问题 。
在获取到后台返回的联系人数据以后,我就将返回的list进行筛选,只是筛选出所需的用户姓名和头像地址.返回字段中,userId和userCode看似一样,其实解析出来,前者是NSNuber类型,后者是NSString类型,当时只记得后台直接使用Sqlite语句,将userCode=userId,根本没有考虑到类型问题.心想,既然这样,不如直接使用userId得了,于是将' [userNameDict setObject:dict[@"userName"] forKey:dict[@"userCode"]];'换成了'[userNameDict setObject:dict[@"userName"] forKey:dict[@"userId"]];'.问题就是出现在换了一个字段上. 。
刚开始没有发现问题,因为之前一直使用userCode字段取值作为字典的key,所以在本地已经有了缓存.直到有一天,重新安装App测试时才发现,聊天界面的头像和昵称都不在显示,才最终想到当初换了了一个字段取值. 。
但是,更换为userId后,打印出来的字典一模一样,就是writeToFile写入plist时总是失败.后来使用isEqualToDictionary方法比较两个字典又是不一样的.问题实在难找,当然解决办法就是切换为原来的userCode,但是遇到问题一向不想通过回避的方式去解决,所以就排查原因,甚至去比较过所有的key和value值,发现还是一样.最后,感觉实在找不出问题所在,于是去查看返回数据,于是便发现了,字段userId和userCode所对应的Value值的类型是不一样的.这才得出一下结论 。
如果是可变字典,那么在使用'setObject: forKey:'方法时,如果key使用的是NSNumber类型的key,会导致writeToFile失败. 。
至于为什么是这样,有待进一步研究,当然,如果有人遇到过并找出原因,也可以回复一下,相互学习,共同进步. 。
附上当时代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
- (
void
)saveContactListDict:(id)list {
NSMutableArray *contactListArray = [NSMutableArray array];
for
(NSDictionary *dict in list) {
for
(NSString *key in dict) {
if
([dict[key] isKindOfClass:[NSArray
class
]]) {
[contactListArray addObjectsFromArray:dict[key]];
}
}
}
NSMutableDictionary *userNameDict = [NSMutableDictionary dictionary];
NSMutableDictionary *avatarurlDict = [NSMutableDictionary dictionary];
NSMutableDictionary *avatarurlAndNameDict = [NSMutableDictionary dictionary];
for
(NSDictionary *dict in contactListArray) {
if
(dict[@
"userId"
] == nil) {
return
;
}
[userNameDict setObject:dict[@
"userName"
] forKey:dict[@
"userId"
]];
NSString *url =dict[@
"avatarUrl"
];
NSString *avatarUrl = [CPUtil getThumUrl:url size:CGSizeMake(
200
,
200
)];
[avatarurlDict setObject:avatarUrl forKey:dict[@
"userId"
]];
if
(dict[@
"userName"
] == nil) {
return
;
}
[avatarurlAndNameDict setObject:avatarUrl forKey:dict[@
"userName"
]];
}
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *userNameDictPath = [path stringByAppendingPathComponent:@
"userNameDict.plist"
];
NSString *avatarurlDictPath = [path stringByAppendingPathComponent:@
"avatarurlDict.plist"
];
NSString *avatarurlAndNameDictPath = [path stringByAppendingPathComponent:@
"avatarurlAndNameDict.plist"
];
[userNameDict writeToFile:userNameDictPath atomically:YES];
[avatarurlDict writeToFile:avatarurlDictPath atomically:YES];
[avatarurlAndNameDict writeToFile:avatarurlAndNameDictPath atomically:YES];
}
|
分析问题 。
实际开发当中,总是有细节的东西,虽然有时候觉得,这些东西太基础,但是就在这些基础的知识上,我们却忽略了一些本应该注意的点.好比说我们明明知道向数组中添加元素的时候,元素不能为空,记得考虑为nil,null的情况.这谁都知道,但是却最容易被忽略,因为你无法确定后台的数据返回什么,包括那些规范文档明确要求不能为nil的字段,都有可能返回一个nil or Null .这个时候开始想静静了.明白这个世界其实没有必然的东西.另外,数组越界问题也一直都在,当然为了防止App直接闪退,你可以选择去覆盖系统的方法......好了,言归正传.我们看一下苹果官方文档,回顾一下基础的东西,文档中关于NSDictionary和writeToFile有下面两段内容 。
NSDictionary 。
*A key-value pair within a dictionary is called an entry. Each entry consists of one object that represents the key and a second object that is that key's value. Within a dictionary, the keys are unique. That is, no two keys in a single dictionary are equal (as determined by isEqual(_:)). In general, a key can be any object (provided that it conforms to the NSCopying protocol—see below), but note that when using key-value coding the key must be a string (see Accessing Object Properties). Neither a key nor a value can be nil; if you need to represent a null value in a dictionary, you should use NSNull.* 。
这里说,字典中的key可以是遵守NSCopying协议的任何对象类型,但是 key-value coding中的key必须是一个string. 。
'- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;' 。
This method recursively validates that all the contained objects are property list objects (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list. 。
这里描述了写入文件的对象要求,也就是平时常用的 NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary这些类型,当然自定义类型不可以. 。
解决问题 。
当然最后的处理就是将NSNumber格式化为NSString,看下代码 。
1
2
|
NSString *dictKey = [NSString stringWithFormat:@
"%@"
,dict[@
"userId"
]];
[userNameDict setObject:dict[@
"userName"
] forKey:dictKey];
|
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我! 。
原文链接:http://www.cnblogs.com/chao8888/p/6491094.html 。
最后此篇关于IOS开发中使用writeToFile时的注意事项的文章就讲到这里了,如果你想了解更多关于IOS开发中使用writeToFile时的注意事项的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!