我對ARC,橋接和某些非免費橋接CF對象仍有點困惑。我目前的困惑在於CFSocket。我很確定我正在清理,但分析工具告訴我,否則。也許我的不和諧讓我看不到漏洞,或者工具是錯誤的。我還沒有準備好指責這個工具,所以我正在尋找其他的眼睛來指出這個問題。例如,我是否缺少一種__bridge
將所有權轉讓給我?爲什麼這被標記爲使用ARC的潛在泄漏?
在我的項目中,使用ARC,我有一個基於TCP的服務器。我們稱這個類爲「MyServer」。在MyServer中,我有一個內部屬性套接字,定義如下:
@property (assign) CFSocketRef socket;
此屬性包含服務器運行時的套接字引用。停止服務器將釋放引用,同時刪除服務器對象。我也試圖清理在啓動服務器的過程中創建的任何可能的泄漏。正是在這個領域,我對靜態分析有一個問題。
服務器開始使用此方法:
的createSocket
方法創建一個套接字(杜),像這樣:
-(BOOL)createSocket
{
BOOL result = YES;
self.socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM,
IPPROTO_TCP, 0, NULL, NULL);
if (self.socket != NULL) {
int reuse = true;
int fileDescriptor = CFSocketGetNative(self.socket);
if (setsockopt(fileDescriptor, SOL_SOCKET, SO_REUSEADDR,
(void *)&reuse, sizeof(int)) == 0) {
struct sockaddr_in address;
memset(&address, 0, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(self.port);
CFDataRef addressData = CFDataCreate(NULL,
(const UInt8 *)&address,
sizeof(address));
if (addressData && CFSocketSetAddress(self.socket, addressData) == kCFSocketSuccess) {
self.listenHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileDescriptor
closeOnDealloc:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receiveIncomingConnectionNotification:)
name:NSFileHandleConnectionAcceptedNotification
object:nil];
[self.listenHandle acceptConnectionInBackgroundAndNotify];
_state = SERVER_STATE_RUNNING;
} else {
result = NO;
[self errorWithName:@"Unable to bind socket to address."];
}
CFRelease(addressData);
} else {
[self errorWithName:@"Unable to set socket options."];
CFRelease(self.socket);
CFSocketInvalidate(self.socket);
CFRelease(self.socket);
self.socket = nil;
result = NO;
}
} else {
[self errorWithName:@"Unable to create socket."];
// CFRelease(self.socket); //NO - CFRelease(NULL) is a runtime error!
result = NO;
}
return result;
}
當我在此代碼運行靜態分析,Xcode的報告self.socket周圍有一堆潛在的泄漏。這裏有一個例子,從上面的createSocket
方法:
這的確是真的,我不引用對象的任何更多的這條道路。也許有一些方法可以告訴系統我想擁有這個對象,並且它抱怨的原因是它不能告訴我這麼做。我是否應該使用__bridge
中的一個來表達這些信息?我試圖讓財產保留或強大,但不建立,因爲它不是一個對象。任何其他想法?
我注意到其他一些執行路徑,我們沒有正確清理,所以我已經調整了相應的邏輯,以便加倍確保我們正確清理。 – Rob