Constructeur de commodité

geekspiritgeekspirit Membre
juillet 2010 modifié dans Objective-C, Swift, C, C++ #1
Bonjour,

J'essaie de faire un constructeur de commodité mais j'ai une erreur :

<br />malloc: *** error for object 0x397d550: double free<br />*** set a breakpoint in malloc_error_break to debug<br />


La classe concernée :

WebData.h
<br />#import &quot;JSON.h&quot;<br />#import &lt;Foundation/Foundation.h&gt;<br /><br /><br />@interface WebData : NSObject {<br />	<br />}<br /><br />// Public funtion<br />+(NSDictionary*)webDataWithParam:(NSDictionary*)param;<br /><br />@end<br />



WebData.m
<br />#import &quot;WebData.h&quot;<br /><br />@interface WebData ()<br /><br />- (NSDictionary*)initWithParam:(NSDictionary*)param;<br />- (NSString*)getHttpAt:(NSString *)url withParam:(NSDictionary*)param;<br /><br />@end<br /><br /><br /><br />@implementation WebData<br /><br /><br /><br /><br /># pragma -<br /># pragma Object methode<br /><br />// Méthode de commodité<br />+(NSDictionary*)webDataWithParam:(NSDictionary*)param { return [[[WebData alloc] initWithParam:param] autorelease]; }<br /><br /><br />// Méthode d&#39;initialisation<br />- (NSDictionary*)initWithParam:(NSDictionary*)param{<br />	<br />	// Url du web service<br />	NSString *url = @&quot;http://xxxxxxxxx/Data.php&quot;;<br />	<br />	// Récupération du code source<br />	NSString *dataSource = [self getHttpAt:url withParam:param];<br />			<br />	// Creation de l&#39;objet Json<br />	SBJSON *JsonObj = [[SBJSON alloc] init];<br />	<br />	// Récupération des données<br />	NSDictionary *resData = [NSDictionary dictionaryWithDictionary:[JsonObj objectWithString:dataSource error:nil]];<br />	<br />	// Vide la mémoire<br />	[JsonObj release]; 	<br />	<br />	return resData;<br />	<br />}<br /><br /><br />// Retourne le source d&#39;une page web<br />- (NSString*)getHttpAt:(NSString *)url withParam:(NSDictionary*)param{<br />	<br />	// Création des paramètres<br />	NSMutableString *strParam = [NSMutableString string];<br />	<br />	// Parcours des Key Value<br />	for (id k in param) { [strParam appendFormat:@&quot;&amp;%@=%@&quot;,k,[param objectForKey:k]]; }	<br />	<br />	// Suppression du premier &amp;<br />	strParam = [strParam substringFromIndex:1];	<br />	<br />	// Encodage des paramètres<br />	NSData *postData = [strParam dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];<br />	<br />	// Taille des paramètres<br />	NSString *postLength = [NSString stringWithFormat:@&quot;%d&quot;, [postData length]];<br />	<br />	// Création de la requête<br />	NSMutableURLRequest *httpRequest = [[[NSMutableURLRequest alloc] init] autorelease];<br />	[httpRequest setValue:@&quot;application/x-www-form-urlencoded charset=utf-8&quot; forHTTPHeaderField:@&quot;Content-Type&quot;];<br />	[httpRequest setValue:postLength forHTTPHeaderField:@&quot;Content-Length&quot;];<br />	[httpRequest setURL:[NSURL URLWithString:url]];<br />	[httpRequest setHTTPMethod:@&quot;POST&quot;];<br />	[httpRequest setTimeoutInterval:10];<br />	[httpRequest setHTTPBody:postData];<br />	<br />	// Création du NSURLConnection<br />	NSError *error; NSURLResponse *response;<br />	NSData *data = [NSURLConnection sendSynchronousRequest:httpRequest returningResponse:&amp;response error:&amp;error];<br />	<br />	return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]autorelease];<br />	<br />}<br /><br /><br /><br /><br /><br /># pragma -<br /># pragma Memory methode<br /><br />// Deallocates the memory occupied by the receiver.<br />- (void)dealloc {<br />	<br />&nbsp; &nbsp; [super dealloc];<br />}<br /><br /><br />@end<br />



Lorsque j'enlève l'autorelease de
<br />+(NSDictionary*)webDataWithParam:(NSDictionary*)param { return [[[WebData alloc] initWithParam:param] autorelease]; }<br />


Je n'ai plus d'erreur :-(

Aidez moi svp


Merci

Réponses

  • mpergandmpergand Membre
    04:21 modifié #2
    Un constructeur est supposé retourner une instance de la classe dans laquelle il est défini, ici WebData.

    Tu ne retournes pas d'instance de WebData, mais un NSDictionary  B)
  • zoczoc Membre
    04:21 modifié #3
    Et accessoirement, tu ne respectes pas les convention d'écriture des méthodes initXXX:
    • Pas d'appel du "constructeur désigné" de la classe mère.
    • Pas de vérification que l'appel de ce constructeur de ne modifie pas "self" et que le nouveau "self" n'est pas nul...

    cf. Objective-C 2.0 programming guide, toussa toussa (same player shoot again  ::) ).

  • geekspiritgeekspirit Membre
    04:21 modifié #4
    C'est en postant que je me suis rendu compte que ma classe ne contenait aucune variable global ...et qu'il ne s'agit en faite que de deux fonctions comme sa posé en plein milieu d'une class. Du coup je l'ai mis ailleurs ou j'en ai d'autre des comme sa. Plus de constructeur de commodité. J'ai laissé le post pour ma curiosité pour savoir d'ou sa venait.

    Par contre je suis curieux de savoir pourquoi je ne respecte pas la regle de nommage pour le init ? C'est la deuxième fois qu'on me le dit, sa m'alerte quelque peut.

    Merci
  • CeetixCeetix Membre
    04:21 modifié #5
    Tiens voilà  en gros comment construitre une méthode init de base. Cet article répond aux deux points que Zoc t'a énoncé.
  • zoczoc Membre
    04:21 modifié #6
    dans 1278860278:

    Par contre je suis curieux de savoir pourquoi je ne respecte pas la regle de nommage pour le init ?

    Pas les règles de nommage, les règles d'implémentation.
Connectez-vous ou Inscrivez-vous pour répondre.