2011-01-13 2 views
0

객관적인 C 언어의 초보자인데 웹 서버를 쿼리하고 반환되는 문자열을 콘솔에 표시하는 함수를 구현하고 있습니다. 루프에서 반복적으로 함수 (getDatafromServer)를 호출합니다. 문제는 처음에는 값을 얻는 반면 다른 시간에는 콘솔에서 나 (null)를 반환한다는 것입니다 ... 포럼에서 메모리 관리 및 체크 아웃을 검색했지만 아무도 작동하지 않았습니다. 너희들이 아래의 코드에서 어디서 잘못되었는지 말해 줄 수 있니? 이 기능에 오토 릴리즈 풀을 사용하고, '복귀'후를 해제 나쁜 생각입니다 미리 감사드립니다 ....목표 C : 처음 호출 할 때 올바른 데이터를 반환하는 함수와 다른 시간을 반환하는 경우 null

@implementation RequestThread 

+(void)startthread:(id)param{ 

while (true) { 
    //NSLog(@"Test threads"); 
    sleep(5); 
    NSLog(@"%@",[self getDatafromServer]); 
} 

} 

+(NSString *) getDatafromServer{ 

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

NSString *myRequestString = @"name=Hello%20&[email protected]"; 

NSData *myRequestData = [NSData dataWithBytes:[myRequestString UTF8String] length:[myRequestString length]]; 

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:@"http://192.168.1.32/gs/includes/widget/getcalls.php?user=asdasd&passw=asdasdasd"]]; 
[request setHTTPMethod:@"POST"]; 
[request setHTTPBody: myRequestData]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"]; 
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 

NSString *myString = [NSString stringWithUTF8String:[returnData bytes]]; 

[myRequestString release]; 
[request release]; 
[returnData release]; 

return myString; 
[pool release]; 
} 

@end 

답변

1

자동 풀 풀에 문제가 있습니다. 첫째, 니콜라이 (Nickolay)가 말했듯이, 석방은 복귀 이후이므로 결코 일어나지 않습니다. 나는 컴파일러 경고를 보지 못하고 놀랐다. -Wall을 "기타 경고 플래그"로 설정하고 "정적 분석기 실행"빌드 옵션을 설정하십시오.

함수 밖에서 반환 된 문자열을 사용하려는 경우 autorelease 풀도 함수 외부에 있어야하며 그렇지 않으면 문자열이 로그에 도착하기 전에 할당 해제 될 수 있습니다. 코드 구조는 다음과 같아야합니다.

+(void)startthread:(id)param 
{ 

    while (true) 
    { 
     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
     //NSLog(@"Test threads"); 
     sleep(5); 
     NSLog(@"%@",[self getDatafromServer]); 
     [pool drain]; // use instead of release in case you move to GC 
    } 
} 

다른 문제는 오류 검사를 수행하지 않는 것입니다. 어떻게 확신 할 수 있습니까 :

  • 서버에 대한 요청이 작동합니까?
  • 서버의 응답은 UTF-8로 인코딩됩니다.

리턴 데이터를 얻은 후에 returnData가 nil인지 확인하고 NSError가 있으면 검사해야합니다. 따라서 다음과 같은 것이 필요합니다.

NSError* error = nil; 
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error]; 
if (returnData == nil) 
{ 
    the error object will be set and contain useful info. 
} 

또한 myString이 nil인지 확인해야합니다. 그럴 경우 응답이 UTF-8로 인코딩되지 않았기 때문입니다. HTTP의 경우 기본 인코딩은 UTF-8이 아니며 ISO-8859-1입니다. 또한 응답의 본문은 문자 데이터가 아닐 수도 있습니다. 데이터를 디코딩하는 방법을 찾으려면 응답을 조사해야합니다.

는 또한, 코드가 Memory Management Rules을 위반

NSError* error = nil; 
NSURLResponse* response = nil; 
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
if (returnData == nil) 
{ 
    // the error object will be set and contain useful info. 
} 
else 
{ 
    // You can get the content type and encoding from the response here. 
} 

편집 : 같은 내가 위에서 게시 된 코드는 정말 보일 것입니다. 할당, 복사 또는 새로 만들기를 통해 myRequestString 또는 returnData을 얻지 못했지만 보존하지 않았으므로 이 아니어야합니다.

+0

안녕하세요 JeremyP, 답변 해 주셔서 감사합니다. 코드를 변경했지만 그 결과는 동일합니다. 첫 번째 iteraction에 대한 가치를 얻으려고하기 전에는 제외하고 이제는 첫 번째와 8 번째에 도달했습니다. 우리가 올바른 경로에있는 것 같아요 ... 서버에서 응답을 UTF8, 나는 올바르게 전에 그것을 .. 설정 한 함수를 한 번 사용하면 잘 작동하지만 두 번째 또는 더 많은 호출 잘 작동하지 않습니다. ... – KooshalB

1

. 풀을 제거하면 모든 것이 잘됩니다.

+0

'[풀 릴리스]'호출은 복귀 후에 위치하므로 호출이 이루어지지 않을 때 풀이 유출됩니다. 그러나 나는 또한 AutoreleasePool의 생성/파괴가 좋은 생각이 아니라고 생각한다. –

+0

@Sylvain : 사실,이 메서드는 무한 루프 내에서 반복적으로 호출되므로 실제로 ** 자동 반환 풀 (ref 계산 된 환경에서)이 있어야합니다. 그렇지 않으면 메모리가 부족합니다. 물론 여기는 잘못된 곳입니다. – JeremyP

+1

@JeremyP : autorelease 풀의 처리가'getDatafromServer' 메쏘드에서 이루어져서는 안되며,'startthread' 메쏘드의 루프에서 이루어져야한다고 말하고 싶습니다. –

관련 문제