Help : comportement bizarre avec awakeFromNib

Philippe49Philippe49 Membre
janvier 2008 modifié dans API AppKit #1
Je sèche sur le comportement suivant de mon programme :

Lorsque j'exécute un certain bloc d'instructions dans awakeFromNib, cela se passe bien.
--> Si je mets ce bloc dans une méthode, et que je l'appelle d'awakeFromNib, cela ne marche plus.
Les paramètres sont des variables de l'instance initialisée dans awakeFromNib (il faut que l'interface soit initialisée pour pouvoir initialiser ces variables).

--> De même, si j'appelle la méthode par l'intermédiaire d'un bouton, j'ai le même échec.

Où chercher ?

Réponses

  • BruBru Membre
    20:59 modifié #2
    Où chercher ?
    Sans code, je ne vois que dans la boule de cristal !

    .
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #3
    Videmment  :o
    <br />-(void) awakeFromNib<br />{<br />	CGFloat cornerRadius=5.0,borderWidth=3.0;<br />	rootLayer=[[self view] layer];<br />	rootLayer.borderColor=CGColorCreateGenericRGB(0.6, 0.6, 0.6, 1.0);<br />	rootLayer.borderWidth=borderWidth;<br />	rootLayer.cornerRadius=cornerRadius;<br />	rootLayer.contentsGravity=kCAGravityResizeAspect;<br />	<br />//	NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@&quot;/Pictures/aquadavinci_ii.jpg&quot;];<br />//	NSData * imageData =[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imagePath]];<br />//	NSBitmapImageRep * bitmapImageRep=[NSBitmapImageRep imageRepWithData:imageData];<br />//	CGImageRef imageRef=[bitmapImageRep CGImage] ;<br />//	rootLayer.contents=(id) imageRef;<br /><br />	[self orderImageIn:self];<br />}<br />//-(void) applicationWillFinishLaunching:(NSNotification*)notification<br />//{<br />//	LOGCMD;<br />//	NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@&quot;/Pictures/aquadavinci_ii.jpg&quot;];<br />//	NSData * imageData =[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imagePath]];<br />//	NSBitmapImageRep * bitmapImageRep=[NSBitmapImageRep imageRepWithData:imageData];<br />//	CGImageRef imageRef=[bitmapImageRep CGImage] ;<br />//	rootLayer.contents=(id) imageRef;<br />//}<br />//<br />//-(void) applicationDidFinishLaunching:(NSNotification*)notification<br />//{<br />//	LOGCMD;<br />//	NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@&quot;/Pictures/aquadavinci_ii.jpg&quot;];<br />//	NSData * imageData =[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imagePath]];<br />//	NSBitmapImageRep * bitmapImageRep=[NSBitmapImageRep imageRepWithData:imageData];<br />//	CGImageRef imageRef=[bitmapImageRep CGImage] ;<br />//	rootLayer.contents=(id) imageRef;<br />//<br />//}<br /><br />-(IBAction) orderImageIn:(id)sender<br />{<br />	NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@&quot;/Pictures/aquadavinci_ii.jpg&quot;];<br />	NSData * imageData =[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imagePath]];<br />	NSBitmapImageRep * bitmapImageRep=[NSBitmapImageRep imageRepWithData:imageData];<br />	CGImageRef imageRef=[bitmapImageRep CGImage] ;<br />	rootLayer.contents=(id) imageRef;<br /><br />//	[rootLayer setNeedsDisplay];<br />	NSLog(@&quot;%@&quot;,rootLayer.contents);<br />	LOGRECT(rootLayer.contentsRect);<br />}<br />
    



    Comme indiqué, cela marche, une belle image se positionne dans le layer.

    Si dans la méthode orderImageIn, j'active la ligne [rootLayer setNeedsDisplay] , pas d'image.

    Si je désactive dans awakeFromNib, et si j'active applicationDidFinishLaunching, un rectangle blanc et noir à  la place de l'image (aux bonnes dimensions)

    En désactivant dans awake et applic.. , le clic sur le bouton orderImageIn ne donne aucune image avec setNeedsDisplay, et le double rectangle noir/blanc sans setNeedsDisplay

    rq: pour CALayer, il n'y a pas de booléen après setNeedsDisplay

  • BruBru Membre
    20:59 modifié #4
    Je ne vois rien qui me choque dans le code.

    Comme je ne pratique pas encore les CALayer, je n'ai malheureusement pas beaucoup d'aide à  t'apporter.
    Eventuellement, dans orderImageIn:, ajoute quelques NSLogs pour tester la chaine imagePath-imageData-bitmapImageRep-imageRef.
    Tu peux aussi relire la propriété contents du layer pour voir si sa mise à  jour a été correctement faite.

    Normalement, si un CALayer se comporte peu ou prou comme un NSview, je ne pense pas que le setNeedsDisplay soit nécessaire après la mise à  jour de contents (cela doit être fait en interne).

    .
  • Philippe49Philippe49 Membre
    20:59 modifié #5
    Question annexe :

    La méthode CGImage définissant la CGImageRef crée l'objet en autorelease.
    Bien pour moi.
    La property contents est avec un attribut retain : @property (retain) id contents
    Encore Ok, la CGImageRef reçoit donc un message CGImageRetain

    Mais une property avec attribut retain s'occupe-t-elle de faire le release lors du changement.
    Ce serait logique (indispensable), mais je ne le vois pas explicitement dans la doc.
  • psychoh13psychoh13 Mothership Developer Membre
    20:59 modifié #6
    Ah bien sûr que lorsque le changement est effectué un release est envoyé à  l'objet remplacé... Dans une méthode bien conçue, ce qui est le cas des property d'Apple, lorsqu'un objet fait un retain il doit obligatoirement faire un release lorsqu'il va perdre les traces de cette objet.
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #7
    Bon j'arrive à  faire marcher tout cela en mode Debug, mais pas encore en mode Release
    Tout simplement en paramétrant le projet pour autoriser l'utilisation de Objective-C garbage Collection



    Code simplifié
    <br />#import &quot;ViewController.h&quot;<br /><br /><br />@implementation ViewController<br /><br /><br /><br />-(void) awakeFromNib<br />{<br />	CGFloat cornerRadius=5.0,borderWidth=3.0;<br />	rootLayer=[[self view] layer];<br />	rootLayer.borderColor=CGAutorelease(CGColorCreateGenericRGB(0.6, 0.6, 0.6, 1.0));<br />	rootLayer.borderWidth=borderWidth;<br />	rootLayer.cornerRadius=cornerRadius;<br />	rootLayer.contentsGravity=kCAGravityResizeAspect;<br />}<br /><br />-(IBAction) orderImageIn:(id)sender<br />{	<br />	NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@&quot;/Pictures/aquadavinci_ii.jpg&quot;];<br />	NSData * imageData =[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imagePath]];<br />	NSBitmapImageRep * bitmapImageRep=[NSBitmapImageRep imageRepWithData:imageData];<br />	CGImageRef imageRef=[bitmapImageRep CGImage] ;<br />	<br />	rootLayer.contents=(id)imageRef;<br />}<br /><br />-(IBAction) orderImageOut:(id)sender<br />{<br />	rootLayer.contents=nil;<br /><br />}<br /><br />-(void) dealloc<br />{<br />	[super dealloc];<br />}<br /><br />@end<br />
    



    CGAutorelease est une macro #define CGAutorelease(x) (__typeof(x))[NSMakeCollectable(x) autorelease]


    [EDIT] bon, honte sur moi, en mode release, il faut aussi régler ce paramètre, et cela marche.
Connectez-vous ou Inscrivez-vous pour répondre.