2009-06-02 10 views
2

我正在与AsyncSocket其中所述AsyncSocket对象调用时,它从远端接收数据低于委托方法工作:现在NSString stringWithCString:length:保留我传入的字节数组?

- (void)onSocket:(AsyncSocket*)socket didReadData:(NSData*)data withTag:(long)tag; 

,在此方法中,我通过NSData对象到以下命令中来获得的数据的的NSString表示接收:

NSString *body = [NSString stringWithCString:[data bytes] length:[data length]; 

确实的NSString stringWithCString:长度:保留字节数组我通过在?我需要保留NSData *数据吗?我需要在最后释放NSString * body吗?

谢谢。我想根据代表方法获得内存管理...

回答

2

是否NSString stringWithCString:length:保留我传入的字节数组?

不可能保留一个字节数组。只有对象可以保留。

我需要保留NSData *数据吗?

不可以。因为字符串没有办法保留数据(它不知道的)或其内容,字符串将复制字节。 (想想如果你正在实施这种方法,你会怎么做:这就是它。)

让我们来改变个案,看看如果你传递数据对象而不是字节,你会做什么。

如果字符串确实保留了数据,那么您不需要担心字符串下的数据将被删除,因为字符串正在保留它。如果它不保留它,那么该字符串要么是自己的副本,要么根本就没有保存你的数据。

所以其他物体的保留并不重要。不要担心他们。只担心谁拥有什么,并保留或不保留。

我是否需要在最后释放NSString * body?

那么,你没有保留它,你没有分配它,你没有复制它。因此,你不拥有它。所以不行。

如果您确实想要取得对象的所有权,您可以保留它或制作(然后拥有)您自己的副本。然后你会释放它。

0

您不必保留NSData数组,因为它的内容将被转换/复制到新的NSString对象中。

返回的NSString对象的保留计数为1,但它已被添加到autorelease池中。
这意味着一旦autorelease池被销毁它就会自动释放。如果你正在使用由AppKit创建的默认自动释放池,这将发生在当前事件循环处理结束时。因此,如果仅在该方法中使用此字符串对象“onsocket:...”,那么您很好。

如果你想保留的NSString对象留下您应该保留它或通过分配和初始化像这样初始化它的方法后:
[[的NSString页头] initWithBytes:[...]长:[。 ..]编码:[...]]
此NSString对象的保留计数为1,但在不再需要时必须将其明确释放。

Btw。 [NSString stringWithCString:length:]已弃用,因为OSX 10.4

0

Pholker是正确的;您应该使用stringWithCString:encoding:来代替。

只有对象需要保留/释放;因为你正在传递一个C字符串(它不是一个对象,不像NSString),所以没有什么可以保留或释放。

由于您使用的是便捷构造 NSString的具有1的保留计数,但被添加到自动释放池,所以在某些时候你离开代码块后,这将被释放。你不需要明确地使用alloc和init方法来保留它。我的意思是,它的保留计数为1(但会被自动释放)。如果你在其上调用保留,它会将计数增加到2,但是在一段时间后,它会自动恢复,并且保留计数将下降为1.

如果您不对对象调用init,retain,copy或mutableCopy,则可以假定它将被自动释放,并且不需要显式释放任何东西。但是如果你想保持一个代码块外的对象,你需要调用retain并在一段时间后释放它(通常在创建对象的类的dealloc方法中)。

1

简单的答案与证明。 NSString stringWithCString:encoding:复制字节缓冲区以生成字符串。缓冲区由您来维护。

证明:

代码:

const char* hardString = "Hello, World"; 
    char *buffer = nil; 

    buffer = calloc(13, 1); 
    bzero(buffer, 13); 

    memcpy(buffer, hardString, 12); 

    NSString *aString = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];   
    NSLog(@"aString: %@ \t filled buffer:(%p) [%s]", aString, (void*)buffer, buffer); 

    bzero(buffer, 13); 
    NSLog(@"aString: %@ \t zeroed buffer:(%p) [%s]", aString, (void*)buffer, buffer); 

    free(buffer); 
    NSLog(@"aString: %@ \t free'd buffer:(%p)", aString, (void*)buffer); 

    buffer = nil;   
    NSLog(@"aString: %@ \t nulled buffer:(%p)", aString, (void*)buffer); 

结果:

aString: Hello, World filled buffer:(0x10010a790) [Hello, World] 
aString: Hello, World zeroed buffer:(0x10010a790) [] 
aString: Hello, World free'd buffer:(0x10010a790) 
aString: Hello, World nulled buffer:(0x0)