2011-10-25 25 views
6

Giả sử tôi nhận được một chuỗi C từ một số chức năng:Memory Management: NSString của stringWithCString: mã hóa:

char * mystring = SomeCFunction(...);

Và tôi sở hữu chuỗi này (tôi chịu trách nhiệm giải phóng nó khi tôi đang làm).

Nếu trong Objective-C, tôi tạo ra một NSString * sử dụng:

NSString * mynsstring = [NSString stringWithCString:mystring 
              encoding:NSUTF8StringEncoding]; 

Tôi vẫn chịu trách nhiệm giải phóng chuỗi C gốc?

Tôi giả sử câu trả lời là có, nhưng tôi không thể tìm thấy câu trả lời cuối cùng trong tài liệu - và chức năng của phương pháp ngược lại (cStringUsingEncoding), trong khi hợp lý, không cho tôi tạm dừng, vì nó xử lý cString giải phóng cho bạn.

Nếu câu trả lời là có, thì tôi cũng chịu trách nhiệm đảm bảo rằng tôi không giải phóng chuỗi c trước khi tôi hoàn thành việc sử dụng NSString * hoặc chức năng sao chép chuỗi cho tôi? Tôi yêu cầu này bởi vì tài liệu cho stringWithCString nói nó:

Trả về một chuỗi chứa các byte trong một mảng C nhất định, giải thích theo một mã hóa nhất định.

Điều gì vẫn khiến tôi tự hỏi liệu nó có thực sự sao chép các byte hay chỉ trỏ vào chúng trong nội bộ (và về cơ bản tôi chỉ làm một diễn viên).

Trả lời

8

Nó sao chép các byte.

Nếu bạn không muốn sao chép các byte, bạn có thể sử dụng - (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)flag để thay thế.

Nếu bạn sử dụng - (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding hoặc bất kỳ phương thức hàng hóa nào giống như stringWithCString:encoding: chính nó gọi phương thức cấp thấp này, các byte được sao chép.

+0

Ah! Bạn thật tuyệt vời. Cảm ơn bạn! Tôi sẽ chấp nhận câu trả lời sau 6 phút còn lại trên bộ đếm giờ chấp nhận đã hết hạn. – Steve

+0

Điều này nên có trên tài liệu –

+0

@ AndréFratelli Tôi đề nghị bạn gửi một phản hồi (có một liên kết ở cuối mỗi trang của tài liệu trực tuyến) để Apple thêm điều này vào đó ;-) – AliSoftware

3

API không biết con trỏ bạn truyền đến từ đâu để không biết cách lấy quyền sở hữu nó. Nó có thể là từ malloc(), nhưng nó cũng có thể là một con trỏ bên trong hoặc từ mmap(), trong trường hợp đó free() sẽ không hoạt động. Vì vậy, API buộc phải sao chép dữ liệu.

Lần duy nhất bạn có thể chuyển quyền sở hữu bộ đệm C cho API Cocoa là nếu API cho phép bạn thông báo rằng nó cần giải phóng. Hãy xem -[NSData initWithBytesNoCopy:length:freeWhenDone:], ví dụ.

+0

+1, Vâng, điều đó khiến rất nhiều ý nghĩa với tôi ... đôi khi tôi chỉ với các tài liệu của Apple là một chút rõ ràng hơn về những thứ như thế này - thay vì để bạn suy luận những điều đó cho chính mình. Trong trường hợp này nó khiến tôi ngần ngại đủ lâu để tôi nghĩ rằng tôi nên hỏi. – Steve

+0

Đủ công bằng. Nộp một lỗi và yêu cầu điều này được gọi một cách rõ ràng trong tài liệu. – kperryua