深入iOS 5:解析兩大隱藏特性
JSON序列化
iOS 5加入了NSJSONSerialization類,可以將JSON和Foundation objects相互轉(zhuǎn)換。來看一段圖片的代碼示例:
- {"taken": "2011/07/13"
- "width": "3072",
- "height": "2304",
- "latitude": "39.52",
- "longitude": "-106.05",
- "url": "http://mypictures.com/12345.png"
- }
解析起來很簡單,代碼示例:
- NSError *error = nil;
- NSData *data = [NSData dataWithContentsOfURL:webServiceURL];
- NSDictionary *photo = [NSJSONSerialization
- JSONObjectWithData:data
- options:NSJSONReadingMutableLeaves
- error:&error];
- NSNumber *width = [photo objectForKey:@"width"];
- NSNumber *height = [photo objectForKey:@"height"];
齊活兒。不要另外去下載類庫啊啥的,示例中的JSONOBjectWithData:options:error:方法具體是將數(shù)據(jù)參數(shù)轉(zhuǎn)向NSDictionary。
NSJSONSerialization可以很容易的將數(shù)據(jù)解析到內(nèi)存或者Stream里,對于大數(shù)據(jù)來說,用Stream的優(yōu)勢更明顯,可以將數(shù) 據(jù)分塊來一點點的處理掉,從而使得內(nèi)存資源得到盡量***的占用。再看一段示例,同上一段不同的是這次使用了JSONOBjectWithStream: variant方法:
- NSError *error = nil;
- NSStream *stream = [self getMyStream];
- NSDictionary *photo = [NSJSONSerialization
- JSONObjectWithStream:stream
- options:NSJSONReadingMutableLeaves
- error:&error];
- NSNumber *width = [photo objectForKey:@"width"];
- NSNumber *height = [photo objectForKey:@"height"];
iOS對JSON的支持甚至更進了一步,可以產(chǎn)生JSON數(shù)據(jù)。
ARC(自動引用計數(shù))
很多用慣了有垃圾回收機制開發(fā)語言的開發(fā)者,用Objective-C會很不習慣,總是要進行很多內(nèi)存管理的工作。蘋果覺得垃圾回收這種嚴重影響電源使用效率的特性,同移動設(shè)備天生的實時性是相沖突的。但是在iOS 5當中蘋果引入了自動內(nèi)存管理機制,稱作ARC。
為了解決保留/釋放內(nèi)存管理,ARC加入了一個新的概念稱作“歸零弱引用”,弱引用一旦不再沒引用機會被清零。至此所有弱引用不再會指向懸擺指針,而是被自動清理掉。
如果你用ARC,那么必須向編譯器聲明你用Core Foundation對象干嗎,否則會報錯。先看一個可以導致報錯的例子:
- NSDictionary *values =
- [NSDictionary dictionaryWithObject:@"object" forKey:@"key"];
- dictionary = (CFDictionaryRef)values;
- SomeFunctionCallThatNeesACFDictionary(dictionary);
如果只是想用dictionary作為CFDictionaryRef類,只需加一個 __bridge 就可以來。再來看正確的示例:
- NSDictionary *values =
- [NSDictionary dictionaryWithObject:@"object" forKey:@"key"];
- CFDictionaryRef dictionary = (__bridge CFDictionaryRef)values;
- SomeFunctionCallThatNeesACFDictionary(dictionary);
- NSDictionary *values =
- [NSDictionary dictionaryWithObject:@"object" forKey:@"key"];
- CFDictionaryRef dictionary = (__bridge CFDictionaryRef)values;
- SomeFunctionCallThatNeesACFDictionary(dictionary);