2010-04-18 6 views
1

나는이 두 가지 방법이 (메모리 할당 방식으로) 동등하다고 생각했지만 편리한 방법 (아래 주석 처리 된)을 사용하고 디버거에서 "범위를 벗어남"및 "NSCFString"을보고있었습니다. 나는 더 명백한 방법으로 전환하여 코드가 충돌을 멈췄다. sqlite3 쿼리에서 컨테이너에 저장되는 문자열을 가져 오는 중입니다. NSString alloc : initWithCString 대 stringWithUTF8String의 차이점은 무엇입니까?

p = (char*) sqlite3_column_text (queryStmt, 1); 
// GUID = (NSString*) [NSString stringWithUTF8String: (p!=NULL) ? p : ""]; 
GUID = [[NSString alloc] initWithCString:(p!=NULL) ? p : "" encoding:NSUTF8StringEncoding]; 

또한, 내가 디버거의 값을 보았고, NSLog로 인쇄하는 경우가 올바른 보인다고주의 그러나 나는 새로운 메모리가 할당하고 값이 복사 된 생각하지 않습니다. 대신 메모리 포인터가 저장되었습니다 - 범위를 벗어났습니다 - 나중에 참조하십시오 - 충돌합니다!

답변

0

메서드가 반환 된 후에도 개체에 대한 참조를 유지해야하는 경우 개체의 소유권을 가져와야합니다. 따라서 변수 GUID이 인스턴스 변수 또는 일종의 전역 변수 인 경우 개체의 소유권을 가져와야합니다. alloc/init 메소드를 사용하면 alloc을 사용한 이후에 반환 된 객체의 소유권을가집니다. stringWithUTF8String: 방법을 쉽게 사용할 수 있지만 retain 메시지를 보내어 소유권을 명시 적으로 가져와야합니다. 그래서, GUID을 가정하는 것은 아닌 방법 - 범위 변수의 어떤 종류는 다음과 같습니다

GUID = [[NSString stringWithUTF8String:"Some UTF-8 string"] copy]; 

(중 문자열을 처리 할 때 copy 또는 소유권을 여기에 사용할 수 있습니다 retain하지만 copy 더 일반적이다).

GUID = p ? [[NSString stringWithUTF8String:p] copy] : @""; 
+0

지금 그 설명은 의미가 있습니다 :

또한, 귀하의 코드는 같은 일을 한 경우에 읽기 좀 더 쉽게하실 수 있습니다! 또한, 나는 그것이 다른 미스테리 추락을 설명한다고 생각한다. – mobibob

관련 문제