à quel objet SELF fait il référence ?

tommyaltaïr

Membre confirmé
5 Mars 2008
25
0
Bonjour, j'ai modifié un programme d'exemple d'Apple (color sampler) afin d'initialiser un crop à l'ouverture de l'application en rajoutant une fonction awakeFromNib. Cette fonction ne marche pas et plan l'appli. Question, le self qui se trouve dans cette fonction, à quel objet fait il référence ?

Bloc de code:
PixelFinder.h

@interface PixelFinderView : NSImageView
	{
	IBOutlet id magnifiedImageView;
	}

- (void) awakeFromNib;
- (void) mouseDown:(NSEvent *) theEvent;
- (void) mouseDragged:(NSEvent *) theEvent;
- (void) mouseUp:(NSEvent *) theEvent;
@end

@interface NSView (snapshot)

- (NSImage *) snapshot;
- (NSImage *) snapshotFromRect:(NSRect) sourceRect;
@end


PixelFinder.m

#import "PixelFinderView.h"

@implementation PixelFinderView

- (void) awakeFromNib
{	
	[magnifiedImageView setImage:[self snapshotFromRect:NSMakeRect(10.0, 15.0, 10, 10)]];
}
- (void) mouseDown:(NSEvent *) theEvent { [self mouseDragged:theEvent]; }
- (void) mouseUp:(NSEvent *) theEvent  { [self mouseDragged:theEvent]; }	
- (void) mouseDragged:(NSEvent *) theEvent
	{
	NSPoint where = [self convertPoint:[theEvent locationInWindow] fromView:nil];  
				
	[magnifiedImageView setImage:[self snapshotFromRect:NSMakeRect(where.x - 5.0, where.y - 5.0, 10, 10)]];
	}
	
@end

NSView_snapshot.h

#import <AppKit/AppKit.h>

@interface NSView  (snapshot)

- (NSImage *) snapshot;
- (NSImage *) snapshotFromRect:(NSRect) sourceRect;

@end

NSView_snapshot.m

#import "NSView_snapshot.h"


@implementation NSView (snapshot)

- (NSImage *) snapshot { return [self snapshotFromRect:[self bounds]]; }
- (NSImage *) snapshotFromRect:(NSRect) sourceRect;
/*"This method creates a new image from a portion of the receiveing view.  The image is returned autoreleased."*/
	{
	NSImage *snapshot = [[NSImage alloc] initWithSize:sourceRect.size];
		
	NSBitmapImageRep *rep;
	
	[self lockFocus];
	rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:sourceRect];
	[self unlockFocus];
	
	[snapshot addRepresentation:rep];
	return [snapshot autorelease];  //  balance the +alloc call..
	}
@end
 
Hello,

self comme il l'indique référence l'objet lui-même. C'est à dire l'objet à qui on a passé le message snapshotFromRect.

C'est le this en java (ou en C++/PHP).
 
Bonjour Bladrak,
L'objet en question est alors l'image sur lequel je clique avec la sourie, une sous classe de NSImageView ? Alors dans la fonction awakeFromNib le code ne peut fonctionner, l'objet n'est pas désigné. Faut il que je modifie l'interface de PielFinderView en rajoutant un lien sur l'objet ( IBOutlet id test) et écrire le code comme cela :
[magnifiedImageView setImage:[test snapshotFromRectP:NSMakeRect(100, 100, 10, 10)]];
 
J'avoue, j'ai pas bien compris la réponse de Tatouille mais bon...
J'ai revu ma copie avec des pdf sur objective C et les choses me semblent plus clair : PixelFinderView est un objet avec des caractéristiques particulières décrites dans les méthodes, vrai ?

En mettant des Breack Point dans le code, j'ai pu m'apercevoir que la méthode awakeFromNib s'exécutait avant que l'appli tourne. J'aurai peu être comme réponse c'est normal. Mais comment faire pour initier un cropp après l'ouverture de l'appli sans agir dans IB et sans utiliser la sourie ?
Je me suis dit qu'il existe peu être une méthode qui m'indique qu'un objet est actif, j'ai pas trouvé.

Help, Help,
 
Voici comment fonctionne le programme d'Apple:

- PixelFinderView est une sous-classe de NSImageView. De fait, elle possède une NSImage (l'image à afficher).

- Sa méthode -snapshotFromRect: renvoie une image qui correspond à la NSImage rognée.

- Sa méthode -snapshot renvoie une image rognée selon son rectangle bounds. Ce rectangle est son rectangle englobant (si la vue a des dimensions de 80x40, bounds = 0,0,80,40). Je ne saisis pas trop l'intérêt de cette méthode.

- La méthode -awakeFromNib est appelée lorsque toutes les outlets sont connectées. Elle fixe l'image de la NSImageView magnifiedImageView à l'image rognée selon le rect 10,15,10,10.

- La méthode -mouseDragged: est appelée lorsque la souris est glissée avec le bouton appuyé. Elle convertit les coordonnées globales en coordonnées locales à la vue, puis affecte à magnifiedImageView l'image rognée selon le rectangle souris.x-5, souris.y-5, 10, 10.
 
Merci Céroce, mais comme dit précédemment, c'est moi qui ai rajouté la méthode -awakeFromNib dans le sample d'Apple, pensant initier un cropp à l'ouverture de l'appli. Cela ne fonctionne pas car cette méthode s'exécute avant la création de la fenêtre de l'appli.
 
Quand awakeFromNib est appelée, ça veut dire que le NIB/XIB a été désarchivé, que les objets qui s'y trouvent on été instanciés et que les liaisons entre eux (actions, outlets, bindings) sont en place.

Cependant, les vues ne sont pas encore affichées.
De fait, que donne l'appel à initWithFocusedViewRect: ?

Maintenant pour résoudre ton problème, ce n'est pas si simple que ça. Il faut être sûr que l'image s'est affichée au moins une fois dans la vue, tu pourrais écrire quelque chose dans ce style:

Bloc de code:
- (void) drawRect:(NSRect)rect
{
	static BOOL	drawnOnce = NO;
	
	[super drawRect:rect];
	
	if(!drawnOnce)
	{
		[magnifiedImageView setImage:[self snapshotFromRect:NSMakeRect(10.0, 15.0, 10, 10)]];
		drawnOnce = YES;
	}
}

Je n'ai pas essayé, mais ça devrait marcher.
Il y a d'autre meilleures solutions (comme celles de ne pas utiliser le code d'exemple d'Apple).
 
En fait, je m'étais fixé un petit exercice, histoire de me remettre en selle dans la pratique de cocoa, afin de faire évoluer une application. Dès le départ semble t'il, j'ai choisi un truc pas commode. Ce choix ne présente pas trop d'intérêt direct sur les modification de mon soft.
Je vais aborder les choses différemments et employer mon énergie vers du possible.
Merci à tous.

Ha oui j'oubliai, un grand merci à la MacGeneration team, le site est agréable tant par les échanges que par la composition graphique de la page web.