cfmutabledictionaryref 和 nsmutablearray初始化dictionary 有什么区别

[精通Objective-C]专家级技巧:使用ARC
ARC和对象所有权
之前的章节已经提到过ARC的基本概念和使用方式。ARC通过(在编译时)插入代码,使向对象发送的retain和release消息达到平衡,从而自动化了该任务。ARC禁止程序员手动控制对象的生命周期,因此,了解ARC内存管理方式中的对象所有权规则就非常重要。
Objective-C程序能够获得由名称以alloc、new、copy或mutableCopy开头的方法创建的任何对象的所有权。如下所示,main()函数用alloc方法创建一个Atom对象,因而声明了这个对象的所有权。
int main(int argc, const char * argv[]) {
@autoreleasepool {
Atom *atom = [[Atom alloc] init];
如前所述,ARC禁止以手动方式向对象发送release、autorelease、dealloc或其他相关的消息。在执行以下3种操作时才会放弃对象的所有权:1.重新分配变量;2.将nil赋予变量;3.释放对象的所有者。
1.重新分配变量
Atom *atom = [[Atom alloc] initWithName:@&Atom1&];
atom = [[Atom alloc] initWithName:@&Atom2&];
这段代码首先创建了一个Atom对象(命名为Atom1),并将之赋予变量atom,稍后又将另一个Atom对象(命名为Atom2)赋予变量atom。因为变量atom已经被重新分配给Atom2,所以Atom1会失去一个所有者,而且如果没有其他所有者的话,它就会被释放掉。
2.将nil赋予变量
Atom *atom = [[Atom alloc] init];
这段代码创建一个Atom对象,并将之赋予变量atom,稍后将变量atom设置为nil,由于变量atom已被设置为nil,所以Atom会失去一个所有者,而且ARC会在将变量atom设置为nil的语句后面,插入向这个Atom对象发送release消息的代码。
3.释放对象的所有者
@interface OrderEntry : NSObject
@public OrderItem *
NSString *orderId;
Address *shippingA
OrderEntry类的初始化方法会创建其两个子类OrderItem类和Address类的实例,因此,当程序创建并初始化一个OrderEntry对象时,会声明它拥有这些子对象的所有权。如果程序释放了该OrderEntry对象,ARC会自动向它的子对象发送release消息。
这里继续使用[Objective-C]内存管理中创建的工程,也可以重新创建一个。下面是测试时需要用到的3个类。
Address类不用做任何改动
@interface Address : NSObject
#import &Address.h&
@implementation Address
-(id) init{
if ((self = [super init])) {
NSLog(@&Initializing Address object&);
-(void) dealloc{
NSLog(@&Deallocating Address object&);
OrderItem类中把实例变量name修改为只读属性
@interface OrderItem : NSObject
@property(readonly) NSString *
-(id) initWithName:(NSString *)itemN
#import &OrderItem.h&
@implementation OrderItem
-(id) initWithName:(NSString *)itemName{
if ((self = [super init])) {
_name = itemN
NSLog(@&Initializing OrderItem object %@&, _name);
-(void) dealloc{
NSLog(@&Deallocation OrderItem object %@&, self.name);
OrderEntry类中,把orderId,item两个实例变量修改为只读属性,并更新初始化方法
#import &OrderItem.h&
#import &Address.h&
@interface OrderEntry : NSObject
Address *shippingA
@property(readonly) NSString *orderId;
@property(readonly) OrderItem *
-(id) initWithId:(NSString *)oid name:(NSString *)
#import &OrderEntry.h&
@implementation OrderEntry
-(id) initWithId:(NSString *)oid name:(NSString *)order{
if ((self = [super init])) {
NSLog(@&Initializing OrderEntry object&);
_orderId =
_item = [[OrderItem alloc] initWithName:order];
shippingAddress = [[Address alloc] init];
-(void) dealloc{
NSLog(@&Deallocation OrderEntry object with ID %@&,self.orderId);
接下来在main.m中进行调试:
#import &OrderEntry.h&
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 创建一个OrderEntry对象
OrderEntry *entry1 = [[OrderEntry alloc] initWithId:@&A-1& name:@&2 Hot dogs&];
NSLog(@&Order 1, ID = %@, item = %@&, entry1.orderId, entry1.item.name);
// 创建另一个OrderEntry对象
OrderEntry *entry2 = [[OrderEntry alloc] initWithId:@&A-2& name:@&Cheeseburger&];
NSLog(@&Order 2, ID = %@, item = %@&, entry2.orderId, entry2.item.name);
// 向集合中添加两个OrderEntry对象
NSArray *entries = [[NSArray alloc] initWithObjects:entry1, entry2, nil];
NSLog(@&Number of order entries = %li&, [entries count]);
// 将指向OrderEntry对象的变量这只为nil,ARC会向该对象发送一条release消息
NSLog(@&Setting entry2 variable to nil&);
// 将指向对象集的变量这只为nil,ARC会向其中包含的每个对象发送一条release消息
NSLog(@&Setting entries to nil&);
// 将指向OrderEntry对象的变量这只为nil,ARC会向该对象发送一条release消息
NSLog(@&Setting entry1 variable to nil&);
// 退出自动释放池代码块
NSLog(@&Leaving autoreleasepool block&);
得到的运行结果如下:
17:16:11.004 ARC Orders[] Initializing OrderEntry object
17:16:11.005 ARC Orders[] Initializing OrderItem object 2 Hot dogs
17:16:11.005 ARC Orders[] Initializing Address object
17:16:11.005 ARC Orders[] Order 1, ID = A-1, item = 2 Hot dogs
17:16:11.005 ARC Orders[] Initializing OrderEntry object
17:16:11.005 ARC Orders[] Initializing OrderItem object Cheeseburger
17:16:11.005 ARC Orders[] Initializing Address object
17:16:11.005 ARC Orders[] Order 2, ID = A-2, item = Cheeseburger
17:16:11.006 ARC Orders[] Number of order entries = 2
17:16:11.006 ARC Orders[] Setting entry2 variable to nil
17:16:11.006 ARC Orders[] Setting entries to nil
17:16:11.006 ARC Orders[] Deallocation OrderEntry object with ID A-2
17:16:11.006 ARC Orders[] Deallocation OrderItem object Cheeseburger
17:16:11.006 ARC Orders[] Deallocating Address object
17:16:11.006 ARC Orders[] Setting entry1 variable to nil
17:16:11.006 ARC Orders[] Deallocation OrderEntry object with ID A-1
17:16:11.006 ARC Orders[] Deallocation OrderItem object 2 Hot dogs
17:16:11.006 ARC Orders[] Deallocating Address object
17:16:11.006 ARC Orders[] Leaving autoreleasepool block
现在对结果进行分析,首先初始化了两个OrderEntry类的对象entry1和entry2,然后将两个OrderEntry对象添加到了NSArray实例之中,之后将变量entry2设置为nil,然而由于NSArray实例仍旧拥有这个OrderEntry对象,所以该对象不会被释放,接下来将变量entries设置为空,这会导致NSArray实例被释放,而且ARC还会向该集合中的每个对象都发送一套release消息。因为entry2对象现在没有其他拥有者了,因此这时候它会被释放,而且所有依赖它的对象会被一起释放。最后将entry1也设置为nil,entry1和所有依赖它的对象也被一起释放。
Objective-C 桥接
ARC能够自动管理Objective-C对象和块对象的内存。而苹果公司提供的基于C语言的API软件库没有与ARC整合。因此,当通过动态方式为这些基于C语言的API分配内存时,必须手动管理内存。实际上,ARC不允许在Objective-C对象的指针和其他数据类型的指针之间进行直接转换,为了方便开发人员在Objective-C程序中使用基于C语言的API,苹果公司提供了如直接桥接和ARC桥接转换等多种机制。
苹果公司为基于C语言的Core Foundation框架和基于Objective-C的Foundation框架中的许多数据类型提供了互用性,这种功能称为直接桥接,以下是一些较常用的直接桥接数据类型。
Core Foundation框架数据类型
Foundation框架数据类型
CFArrayRef
CFDictionaryRef
NSDictionary
CFMutableArrayRef
NSMutableArray
CFMutableDataRef
NSMutableData
CFMutableDictionaryRef
NSMutableDictionary
CFTableSetRef
NSTableSet
CFTableStringRef
NSTableString
CFNumberRef
CFReadStreamRef
NSInputStream
CFWriteStreamRef
NSOutputStream
CFStringRef
以下是一个用直接桥接的方式将CFStringRef类型变量用作参数的Objective-C方法:
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFStringRef cstr = CFStringCreateWithCString(NULL, &Hello,World!&, kCFStringEncodingASCII);
// 等价于 NSArray *data = [NSArray arrayWithObject:(NSString *)cstr];
NSArray *data = [NSArray arrayWithObject:cstr];
NSLog(@&Array size = %ld&, [data count]);
但是在使用ARC时,直接桥接是无法通过编译的,这时候就需要使用ARC桥接转换。
ARC桥接转换
ARC桥接转换的操作必须将特殊标志__bridge,__bridge_retained和__bridge_transfer用作前缀转换。
使用__bridge标记可以在不改变所有权的情况下,将对象从Core Foundation框架数据类型转换为Foundation框架数据类型(反正亦然)
使用__bridge_retained标记可以将Foundation框架数据类型对象转化为Core Foundation框架数据类型对象,并从ARC接管对象的所有权,对象将可以手动管理。
使用__bridge_transfer标记可以将Core Foundation框架数据类型对象转化为Foundation框架数据类型对象,并将对象的所有权交给ARC管理。
以下是使用不同前缀来进行ARC桥接转换的例子:
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFStringRef cstr = CFStringCreateWithCString(NULL, &Hello,World!&, kCFStringEncodingASCII);
// 使用__bridge标记不会改变对象所有权管理方式,所以必须手动管理CFStringRef类型对象的声明周期
NSArray *data = [NSArray arrayWithObject:(__bridge NSString *)cstr];
// 如果注释掉该语句,程序可以正常输出结果,但通过Product-&Analyze会检测出内存泄漏,需要手动释放cstr
CFRelease(cstr);
NSLog(@&Array size = %ld&, [data count]);
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFStringRef cstr = CFStringCreateWithCString(NULL, &Hello,World!&, kCFStringEncodingASCII);
// 使用__bridge_transfer标记会将对象所有权交给ARC自动管理
NSArray *data = [NSArray arrayWithObject:(__bridge_transfer NSString *) cstr];
NSLog(@&Array size = %ld&, [data count]);10:42 提问
NSMutableDictionary的问题
IOS开发代码:
listOfItems NSMutableArray声明:
@interface SAMasterViewController () {
NSMutableArray *listOfI
现在,有一部分代码报出错误:EXC_BAD_ACCESS (code=1, address=0x5fc260000),出在最后一行individual_data对象中。
listOfItems = [[NSMutableArray alloc] init];
for(NSDictionary *tweetDict in statuses) {
= [tweetDict objectForKey:@"text"];
*screenName
= [[tweetDict objectForKey:@"user"] objectForKey:@"screen_name"];
= [[tweetDict objectForKey:@"user"] objectForKey:@"profile_image_url"];
NSInteger unique_id
= [[tweetDict objectForKey:@"id"] intValue];
NSInteger user_id
= [[[tweetDict objectForKey:@"user"] objectForKey:@"id"] intValue ];
NSMutableDictionary *individual_data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
text, @"text_tweet",
screenName,@"user_name",
img_url, @"img_url",
unique_id, @"unique_id",
user_id, @"user_id", nil];
[listOfItems addObject:individual_data];
按赞数排序
你可以参考一下这个帖子的解决办法:
其他相关推荐拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3a7ed09c1547436a-ua98).
重新安装浏览器,或使用别的浏览器NSArray,NSMutableArray,NSDictionary,NSMutableDictionary小结 - Neo_gl的专栏 - CSDN博客
NSArray,NSMutableArray,NSDictionary,NSMutableDictionary小结
#表示返回值类型 :有参数
Creating&an&Array(创建数组
#instancetype
Initializing&an&Array(初始化数组)
#instancetype
Querying&an&Array(查询数组)
#NSInteger
Finding&Objects&in&an&Array(找出数组中的对象)
#NSUIteger
Comparing&Arrays
Deriving&New&Arrays
NSMutableArray
Creating&and&Initializing&a&Mutable&Array(创建和初始化可变数组)
#intancetype
+&arrayWithCapacity:
Adding&Objects(添加对象)
Removing&Objects(删除对象)
Replacing&Objects(替换对象)
NSDictionary
Creating&a&Dictionary(创建字典)
#instancetype
Initializing&an&NSDictionary&Instance(初始化字典实例)
#instancetype
Counting&Entries(计数条目)
#NSINteger
Comparing&Dictionaries(比较字典)
Accessing&Keys&and&Values(访问键和值)
Storing&Dictionaries(存储字典)
NSMutableDictionary
Creating&and&Initializing&a&Mutable&Dictionary(创建初始化可变字典)
#intancetype
Adding&Entries&to&a&Mutable&Dictionary(添加条目进可变字典)
Removing&Entries&From&a&Mutable&Dictionary(移除条目从字典)
我的热门文章}

我要回帖

更多关于 nsmutablearray 排序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信