可以使用堆栈变量优化目标c调用吗?

时间:2013-05-24 18:42:07

标签: objective-c optimization memory-management stack

我错过了什么,或者调用sendData我真的需要在堆上创建3个NS对象吗?或者这甚至是在堆上创建的?反正有没有在堆栈上创建它们?这似乎效率低下!

NSData *data = [NSData dataWithBytes:packet->data length:packet->dataLength];
if(!data)
    return -5;
NSString *player = [NSString initWithCString:(char*)peer->data encoding:NSASCIIStringEncoding];
if(!player)
    return -6;
NSArray *to = [NSArray arrayWithObject:player];
if(!to)
    return -7;

NSError *error;
BOOL success = [[GCHelper sharedInstance].match sendData:data toPlayers:to withDataMode:GKMatchSendDataReliable error:&error];
if (!success) {
    printf("Error sending packet %08x %d\n", packet->data, packet->dataLength);
    return -8;
}

我可以这样做吗?

NSData data;
[data dataWithBytes:packet->data length:packet->dataLength];
NSString player;
[player initWithCString:(char*)peer->data encoding:NSASCIIStringEncoding];
NSArray to;
[to arrayWithObject:player];

对不起我的无知,我精通C ++但不熟悉Objective-C。

2 个答案:

答案 0 :(得分:1)

  

我可以这样做吗?

没有。除了-init和朋友没有实际初始化这一事实(看看NSObject.mm,它所做的只是return self;),你只是对那些消息没有消息调用。 +alloc仅用于提供与实现无关的分配器功能;碰巧在堆上分配对象的那个。如果您担心Objective-C本身的性能,那么您不必使用它。您可以随时回退到C和C ++,然后返回堆栈分配的变量和您熟悉并喜爱的复杂指针算法。 Objective-C仍然是一种高效的语言,尽管它“效率低下”。

请记住:虽然C和C ++专为嵌入式系统和关键任务应用程序而设计,其中内存和处理器效率是最佳选择,但Objective-C旨在运行在相当一致,高性能和(相对)内存无约束的硬件上。 / p>

答案 1 :(得分:1)

如果性能存在问题,则替代。正如你在回答我对这个问题的评论时正确地指出的那样,你不可能添加自己的方法,当你调用框架时,它会将你的数据作为C指针。但是,您可以在一个级别执行类似操作,您可以创建NSDataNSString 而无需将数据本身复制到堆中:

NSData *data = [NSData dataWithBytesNoCopy:packet->data
                                    length:packet->dataLength
                              freeWhenDone:NO];
if(!data)
   return -5;

NSString *player = [NSString initWithBytesNoCopy:peer->data
                                          length:strlen(peer->data)
                                        encoding:NSASCIIStringEncoding
                                    freeWhenDone:NO];
if(!player)
   return -6;

NSError *error;
BOOL success = [[GCHelper sharedInstance].match sendData:data
                                               toPlayers:@[player] // array expression
                                            withDataMode:GKMatchSendDataReliable
                                                   error:&error];
if (!success)
{
   printf("Error sending packet %08x %d\n", packet->data, packet->dataLength);
   return -8;
}

这仍然将您的数据包装为堆对象,但NSDataNSString堆对象都不直接引用您的数据。只要当然需要,您必须确保您的数据保持活跃状态​​!

注意:如果您进入Objective-C并且经常需要此功能,那么您可以将上述代码作为类别包装在GKMatch上 - 这是一个练习: - )