Lecture des données d'un fichier

npantinpanti Membre
novembre 2009 modifié dans API AppKit #1
Salut à  tous,

Je suis occupé à  lire "Cocoa Programming for Mac OS X" et j'essaye de faire le challenge 18.
Je dois créer un programme (document-based) qui permet de dessiner une forme ovale avec la souris dans une Custon View et je dois aussi pouvoir enregistrer le document.

Le problème c'est que lorsque j'ouvre un fichier rien ne s'affiche les ovales enregistrés n'apparaissent pas.

J'ai vérifié, mon fichier enregistré comprend bien le tout les objets contenu dans bezierPaths

Merci d'avance pour votre aide

Nicolas

Voici le code:
mydocument.h
#import &lt;Cocoa/Cocoa.h&gt;<br />@class StretchView;<br /><br />@interface MyDocument : NSDocument<br />{<br />	IBOutlet StretchView *stretchView;<br />}<br /><br />@end


mydocument.m
#import &quot;MyDocument.h&quot;<br />#import &quot;StretchView.h&quot;<br /><br />@implementation MyDocument<br /><br />- (id)init<br />{<br />&nbsp; &nbsp; self = [super init];<br />&nbsp; &nbsp; if (self) {<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; // Add your subclass-specific initialization here.<br />&nbsp; &nbsp; &nbsp; &nbsp; // If an error occurs here, send a [self release] message and return nil.<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}<br /><br />#pragma mark window<br /><br />- (NSString *)windowNibName<br />{<br />&nbsp; &nbsp; // Override returning the nib file name of the document<br />&nbsp; &nbsp; // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.<br />&nbsp; &nbsp; return @&quot;MyDocument&quot;;<br />}<br /><br />- (void)windowControllerDidLoadNib:(NSWindowController *) aController<br />{<br />&nbsp; &nbsp; [super windowControllerDidLoadNib:aController];<br />&nbsp; &nbsp; // Add any code here that needs to be executed once the windowController has loaded the document&#39;s window.<br />}<br /><br />- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError<br />{<br />&nbsp; &nbsp; [[stretchView window] endEditingFor:nil];<br />	<br />	return [NSKeyedArchiver archivedDataWithRootObject:[stretchView bezierPaths]];<br />}<br /><br />- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError<br />{<br />	NSMutableArray *newBezierPaths = nil;<br />	<br />	@try {<br />		newBezierPaths = [NSKeyedUnarchiver unarchiveObjectWithData:data];<br />	}<br />&nbsp; &nbsp; @catch (NSException *e) {<br />		if (outError) {<br />			NSDictionary *d = [NSDictionary dictionaryWithObject:@&quot;The data is corrupted.&quot; <br />														&nbsp; forKey:NSLocalizedFailureReasonErrorKey];<br />			*outError = [NSError errorWithDomain:NSOSStatusErrorDomain <br />											code:unimpErr <br />										userInfo:d];<br />		}<br />	}<br />	<br />	[stretchView setBezierPaths:newBezierPaths];<br />&nbsp; &nbsp; return YES;<br />}<br /><br />@end


stretchview.h
#import &lt;Cocoa/Cocoa.h&gt;<br /><br /><br />@interface StretchView : NSView {<br />	<br />	NSMutableArray *bezierPaths;<br />	NSPoint firstPoint;<br />	NSPoint currentPoint;<br />}<br />- (NSRect)convertToRect;<br />- (void)drawOval:(NSRect)ovalRect;<br /><br />@property (readwrite, retain) NSMutableArray *bezierPaths;<br />@end


stretchview.m
#import &quot;StretchView.h&quot;<br /><br /><br />@implementation StretchView<br /><br />- (id)initWithFrame:(NSRect)frame {<br />&nbsp; &nbsp; self = [super initWithFrame:frame];<br />&nbsp; &nbsp; if (self) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // Initialization code here.<br />		if ([bezierPaths count]) {<br />			for (NSBezierPath *sPath in bezierPaths)<br />			{<br />				[sPath fill];<br />			}<br />		}<br />		else {<br />			bezierPaths = [[NSMutableArray alloc] init];<br />		}<br />		<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}<br /><br />- (void)drawRect:(NSRect)dirtyRect {<br />&nbsp; &nbsp; // Drawing code here.<br />	NSRect bounds = [self bounds];<br />	[[NSColor greenColor] set];<br />	[NSBezierPath fillRect:bounds];<br />	<br />	[[NSColor blackColor] set];<br />	[self drawOval:[self convertToRect]];<br />	<br />	for (NSBezierPath *sPath in bezierPaths)<br />	{<br />		[sPath fill];<br />	}<br />	<br />}<br /><br />- (void)drawOval:(NSRect)ovalRect<br />{<br />	NSBezierPath *thePath = [NSBezierPath bezierPathWithOvalInRect:ovalRect];<br />	[bezierPaths addObject:thePath];<br />}<br /><br />- (NSRect)convertToRect<br />{<br />	float minX = MIN(firstPoint.x, currentPoint.x);<br />	float minY = MIN(firstPoint.y, currentPoint.y);<br />	float maxX = MAX(firstPoint.x, currentPoint.x);<br />	float maxY = MAX(firstPoint.y, currentPoint.y);<br />	<br />	return NSMakeRect(minX, minY, maxX - minX, maxY - minY); <br />}<br /><br />#pragma mark mouseGesture<br /><br />- (void)mouseDown:(NSEvent *)event<br />{<br />	NSPoint p = [event locationInWindow];<br />	firstPoint = [self convertPoint:p fromView:nil];<br />	currentPoint = firstPoint;<br />}<br />					<br />- (void)mouseDragged:(NSEvent *)event<br />{<br />	NSPoint p = [event locationInWindow];<br />	currentPoint = [self convertPoint:p fromView:nil];<br />}<br />					<br />- (void)mouseUp:(NSEvent *)event<br />{<br />	NSPoint p = [event locationInWindow];<br />	currentPoint = [self convertPoint:p fromView:nil];<br />	[self setNeedsDisplay:YES];<br />	<br />}<br /><br />@synthesize bezierPaths;<br /><br />@end

Réponses

  • laudemalaudema Membre
    21:42 modifié #2
    dans 1259175355:


    J'ai vérifié, mon fichier enregistré comprend bien le tout les objets contenu dans bezierPaths

    Merci d'avance pour votre aide

    Bonjour,

    Met un point d'arrêt dans MyDocument et un dans StretchView. Dans le premier tu vérifies qu'il a bien un NS(Mutable)Array avec des données dedans et dans le second qu'il est toujours là  quand tu en as besoin. Le fichier c'est sur le disque, le dessin c'est beaucoup plus loin..
  • npantinpanti Membre
    novembre 2009 modifié #3
    Après avoir un peu relu mon code j'ai fais quelque erreur, mais cela ne corrige toujours pas le problème.

    J'ai mis un point d'arrêt dans la fonction setStretchView, la variable stretch contient bien tout les objets enregistrés mais quand j'appuie sur continuer il revient sur la fonction setStretchView et la stretch ne contient plus rien.

    voici les modifications:
    #import &lt;Cocoa/Cocoa.h&gt;<br />@class StretchView;<br /><br />@interface MyDocument : NSDocument<br />{<br />	IBOutlet StretchView *stretchView;<br />}<br />- (void)setStretchView:(StretchView *)a;<br /><br />@end
    

    #import &quot;MyDocument.h&quot;<br />#import &quot;StretchView.h&quot;<br /><br />@implementation MyDocument<br /><br />- (id)init<br />{<br />&nbsp; &nbsp; self = [super init];<br />&nbsp; &nbsp; if (self) {<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; // Add your subclass-specific initialization here.<br />&nbsp; &nbsp; &nbsp; &nbsp; // If an error occurs here, send a [self release] message and return nil.<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}<br /><br />- (void)dealloc<br />{<br />	[stretchView release];<br />	[super dealloc];<br />}<br /><br />- (void)setStretchView:(StretchView *)stretch<br />{<br />	[stretch retain];<br />	[stretchView release];<br />	stretchView = stretch;<br />}<br /><br />#pragma mark window<br /><br />- (NSString *)windowNibName<br />{<br />&nbsp; &nbsp; // Override returning the nib file name of the document<br />&nbsp; &nbsp; // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.<br />&nbsp; &nbsp; return @&quot;MyDocument&quot;;<br />}<br /><br />- (void)windowControllerDidLoadNib:(NSWindowController *) aController<br />{<br />&nbsp; &nbsp; [super windowControllerDidLoadNib:aController];<br />&nbsp; &nbsp; // Add any code here that needs to be executed once the windowController has loaded the document&#39;s window.<br />}<br /><br />- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError<br />{<br />&nbsp; &nbsp; [[stretchView window] endEditingFor:nil];<br />	<br />	return [NSKeyedArchiver archivedDataWithRootObject:stretchView];<br />}<br /><br />- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError<br />{<br />	StretchView *newStretchView = nil;<br />	<br />	@try {<br />		newStretchView = [NSKeyedUnarchiver unarchiveObjectWithData:data];<br />	}<br />&nbsp; &nbsp; @catch (NSException *e) {<br />		if (outError) {<br />			NSDictionary *d = [NSDictionary dictionaryWithObject:@&quot;The data is corrupted.&quot; <br />														&nbsp; forKey:NSLocalizedFailureReasonErrorKey];<br />			*outError = [NSError errorWithDomain:NSOSStatusErrorDomain <br />											code:unimpErr <br />										userInfo:d];<br />		}<br />	}<br />	<br />	[self setStretchView:newStretchView];<br />&nbsp; &nbsp; return YES;<br />}<br /><br />@end
    

    #import &lt;Cocoa/Cocoa.h&gt;<br /><br /><br />@interface StretchView : NSView &lt;NSCoding&gt; {<br />	<br />	NSMutableArray *bezierPaths;<br />	NSPoint firstPoint;<br />	NSPoint currentPoint;<br />	BOOL mouseUp;<br />}<br />- (NSRect)convertToRect;<br />- (void)drawOval:(NSRect)ovalRect;<br /><br />@end
    

    <br />#import &quot;StretchView.h&quot;<br /><br /><br />@implementation StretchView<br /><br />- (id)initWithFrame:(NSRect)frame {<br />&nbsp; &nbsp; self = [super initWithFrame:frame];<br />&nbsp; &nbsp; if (self) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // Initialization code here.<br />		mouseUp = YES;<br />		bezierPaths = [[NSMutableArray alloc] init];<br />		<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}<br /><br />- (void)dealloc<br />{<br />	[bezierPaths release];<br />	[super dealloc];<br />}<br /><br />#pragma mark coding<br /><br />- (id)initWithCoder:(NSCoder *)decoder<br />{<br />	[super init];<br />	bezierPaths = [[decoder decodeObjectForKey:@&quot;bezierPaths&quot;] retain];<br />	return self;<br />}<br /><br />- (void)encodeWithCoder:(NSCoder *)coder<br />{<br />	[coder encodeObject:bezierPaths forKey:@&quot;bezierPaths&quot;];<br />}<br /><br />#pragma mark drawing<br /><br />- (void)drawRect:(NSRect)dirtyRect {<br />&nbsp; &nbsp; // Drawing code here.<br />	NSRect bounds = [self bounds];<br />	[[NSColor greenColor] set];<br />	[NSBezierPath fillRect:bounds];<br />	<br />	[[NSColor blackColor] set];<br />	[self drawOval:[self convertToRect]];<br />	<br />}<br /><br />- (void)drawOval:(NSRect)ovalRect<br />{<br />	NSBezierPath *thePath = [NSBezierPath bezierPathWithOvalInRect:ovalRect];<br />	<br />	if(mouseUp) {<br />		[bezierPaths addObject:thePath];<br />	}<br />	else {<br />		[thePath fill];<br />	}<br /><br />	for (NSBezierPath *sPath in bezierPaths)<br />	{<br />		[sPath fill];<br />	}<br />	<br />}<br /><br />- (NSRect)convertToRect<br />{<br />	float minX = MIN(firstPoint.x, currentPoint.x);<br />	float minY = MIN(firstPoint.y, currentPoint.y);<br />	float maxX = MAX(firstPoint.x, currentPoint.x);<br />	float maxY = MAX(firstPoint.y, currentPoint.y);<br />	<br />	return NSMakeRect(minX, minY, maxX - minX, maxY - minY); <br />}<br /><br />#pragma mark mouseGesture<br /><br />- (void)mouseDown:(NSEvent *)event<br />{<br />	NSPoint p = [event locationInWindow];<br />	firstPoint = [self convertPoint:p fromView:nil];<br />	currentPoint = firstPoint;<br />	mouseUp = NO;<br />}<br />					<br />- (void)mouseDragged:(NSEvent *)event<br />{<br />	NSPoint p = [event locationInWindow];<br />	currentPoint = [self convertPoint:p fromView:nil];<br />	[self setNeedsDisplay:YES];<br />}<br />					<br />- (void)mouseUp:(NSEvent *)event<br />{<br />	NSPoint p = [event locationInWindow];<br />	currentPoint = [self convertPoint:p fromView:nil];<br />	mouseUp = YES;<br />	[self setNeedsDisplay:YES];<br />}<br /><br /><br />@end
    
  • laudemalaudema Membre
    21:42 modifié #4
    dans 1259182357:

    J'ai mis un point d'arrêt dans la fonction setStretchView, la variable stretch contient bien tout les objets enregistrés mais quand j'appuie sur continuer il revient sur la fonction setStretchView et la stretch ne contient plus rien.


    Au moins tu sais pourquoi il n'affiche rien ;) Mais pourquoi y revient il avec un argument vide ? Tu as fait un binding de stretchView dans IB ou juste connecté l'outlet ?
    En grisé dans le debugger tu peux voir la pile des appels et peut être, par là , savoir d'où vient ce deuxième ?

    PS: ne met pas tout ton code stp, ça fait de longues pages et il faut chercher. Juste les parties intéressantes ie partout où apparaà®t stretchView
  • npantinpanti Membre
    21:42 modifié #5
    J'ai défini la Class de ma CustomView comme étant StretchView et j'ai connecté l'outlet stretchView à  StretchView
  • laudemalaudema Membre
    21:42 modifié #6
    dans 1259239843:

    J'ai défini la Class de ma CustomView comme étant StretchView et j'ai connecté l'outlet stretchView à  StretchView


    Désolé de ne pouvoir aider plus,

    Tu pourrais essayer le "forum" du livre http://techstra.bignerdranch.com/Home, taper N° de page dans le champ de recherche (253 par ex). Un des commentaires donne un lien pour le code de l'exemple résolu.
  • npantinpanti Membre
    21:42 modifié #7
    Je vais analyser ça, j'avais pas vu qu'on pouvait indiquer la page, tout bon cette fonction  ;)
Connectez-vous ou Inscrivez-vous pour répondre.