SudzC для iPhone, кажется, теряет 1 КБ каждый вызов веб-службы
Instruments сообщает о 2 объектах, просочившихся при каждом обращении к Soap Web Service с кодом, созданным SudzC.
Я сузил его до простого случая, используя код, вызывающий бесплатный общедоступный веб-сервис ( http://www.webservicex.net/geoipservice.asmx?WSDL) и без аутентификации. К сожалению, для запуска проекта SudzC требуется много настроек, но вы можете увидеть сгенерированный код, поместив URL-адрес WSDL на http://www.sudzc.com/ и выбрав "Objective-C from iOS".
Leaked Object # Address Size Responsible Library Responsible Frame
Malloc 1.00 KB, 0x5035400 1.00 KB Foundation-[NSCFString appendString:]
NSCFString, 0x4c3d390 32 Bytes Foundation -[NSPlaceholderMutableString init]
Стек вызовов для каждого объекта
3 Foundation -[NSCFString appendString:]
4 SoapDemo +[Soap createEnvelope:forNamespace:forParameters:withHeaders:] /Users/user1/Desktop/SRC/SoapDemo/SoapDemo/Soap/Soap.m:50
5 SoapDemo +[Soap createEnvelope:forNamespace:withParameters:withHeaders:] /Users/user1/Desktop/SRC/SoapDemo/SoapDemo/Soap/Soap.m:114
6 SoapDemo -[WSXGeoIPService GetGeoIP:action:IPAddress:] /Users/user1/Desktop/SRC/SoapDemo/SoapDemo/Generated/WSXGeoIPService.m:55
7 SoapDemo -[SoapDemoViewController callWebService] /Users/user1/Desktop/SRC/SoapDemo/SoapDemo/SoapDemoViewController.m:14
8 SoapDemo -[SoapDemoViewController press:] /Users/user1/Desktop/SRC/SoapDemo/SoapDemo/SoapDemoViewController.m:19
Телефонный код:
- (IBAction)press:(id)sender {
NSLog(@"pressed");
[self callWebService];
}
-(void)callWebService {
WSXGeoIPService* service = [WSXGeoIPService service];
[service GetGeoIP:self action:@selector(handleResponse:) IPAddress:@"209.85.147.103"];
}
-(void) handleResponse:(id)value{
NSLog(@"%@", value);
}
Оскорбительная строка в Soap.m в соответствии с инструментами в [Soap createEnvelope] выглядит довольно безобидно (помечено комментарием).
+ (NSString*) createEnvelope: (NSString*) method forNamespace: (NSString*) ns forParameters: (NSString*) params withHeaders: (NSDictionary*) headers
{
NSMutableString* s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendFormat: @"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns=\"%@\">", ns];
if(headers != nil && headers.count > 0) {
[s appendString: @"<soap:Header>"];
for(id key in [headers allKeys]) {
if([[headers objectForKey: key] isMemberOfClass: [SoapNil class]]) {
[s appendFormat: @"<%@ xsi:nil=\"true\"/>", key];
} else {
[s appendString:[Soap serializeHeader:headers forKey:key]];
}
}
[s appendString: @"</soap:Header>"];
}
[s appendString: @"<soap:Body>"];
[s appendFormat: @"<%@>%@</%@>", method,[params stringByReplacingOccurrencesOfString:@"&" withString:@"&"], method];
[s appendString: @"</soap:Body>"];
[s appendString: @"</soap:Envelope>"]; // *** this is reported as causing the leak ***
return s;
}
Я попытался изменить метод (путем объединения вызовов appendString, добавления некоторых фиктивных журналов и т. Д.), Но утечка всегда происходит в этом методе.
Я могу думать о нескольких возможностях:
- В другом месте кода есть утечка, которую Instruments идентифицирует неправильно.
- appendString используется неправильно.
- В методе appendString компании Apple NSMutableString есть утечка.
- Там нет фактической утечки.
Кто-нибудь может сделать вывод, что происходит (или как это выяснить)?
Я использую iOS SDK 4.3.
План Б заключается в преобразовании проекта в автоматический подсчет ссылок...
1 ответ
Для тех, кто этого не делает, пожалуйста, следуйте моим изменениям, чтобы исправить утечки, так как это прекрасно работает:
- В SoapRequest.h замените объявление переменной
id postData
вNSString* postData
- В SoapRequest.h замените объявление своего свойства на
@property (copy, nonatomic) NSString* postData
(Здесь я дополнительно изменил все деления свойств NSString на "copy") - В SoapRequest.m, метод
(SoapRequest*) create: (SoapHandler*) handler action: (SEL) action urlString: (NSString*) urlString soapAction: (NSString*) soapAction postData: (NSString*) postData deserializeTo: (id) deserializeTo
изменить строкуrequest.postData = [postData retain]
вrequest.postData = postData
,
Эти 3 шага решат ваши проблемы. Надеюсь, что это будет также реализовано в рамках SudzcC.