• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

Programm rechnet zeigt aber nichts an, wenn Methode manuel aufgerufen wird

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
Ja, also zuerst die Funktionalität, aber jetzt werde ich versuche das Programm bisschen mehr "effizienter" zu machen, also, dass es halt schneller läuft und so weiter, war ja wegen nem Schulprojekt, und wenn ich das unter XP ausführe das Programm (unter virtuel PC, voll langsam), dann braucht das etwas länger, die XP Version ist in Pascal geschrieben und macht tausendmal mehr her als meine ObjC Lösung, aber daran werde ich jetzt in Zukunft arbeiten.
Danke

EDIT: habe gesucht, aber keine Möglichkeit gefunden, die Höhe und Breite eine NSView ausgeben zu lassen, gibt es da ein Befehl für? Oder muss man das selbst was schreiben?
 
Zuletzt bearbeitet:

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Du kannst das so auslesen:

Code:
NSRect viewBounds = [myView bounds];
int width = viewBounds.size.width;
int height = viewBounds.size.height;

// mach was damit :)

Definition von NSRect:
Code:
typedef struct _NSRect {
   NSPoint origin;
   NSSize size;
} NSRect;

NSPoint:
Code:
typedef struct _NSPoint {
   CGFloat x;
   CGFloat y;
} NSPoint;

NSSize:
Code:
typedef struct _NSSize {
   CGFloat width;
   CGFloat height;
} NSSize;

grz. ppocket
 

Amin Negm-Awad

Süsser Pfaffenapfel
Registriert
01.03.07
Beiträge
665
Du kannst das so auslesen:

Code:
NSRect viewBounds = [myView bounds];
int width = viewBounds.size.width;
int height = viewBounds.size.height;

// mach was damit :)
Nur als Ergänzung zum völlig richtigen Code von Poljpocket, aber weil es nicht offensichtlich ist:

Da in Objective-C Strukturen By-Value behandelt werden, kann man tatsächlich auch
Code:
NSSize viewSize = [myView bounds].size;
int width = viewSize.width;
int height = viewSize.height;

// mach was damit :)
schreiben.
 

Poljpocket

Salvatico di Campascio
Registriert
07.01.07
Beiträge
432
Ich hab mir auch überlegt, das gleich mit reinzunehmen... :) Danke für die Ergänzung!

Wenn man alles offensichtlich machen will, CGFloat ist im Allgemeinen ein ganz normaler 'float', außer man arbeitet mit 64-bit Systemen, da ist es ein 'double'.

Code:
typedef float CGFloat;   // 32-bit

typedef double CGFloat;  // 64-bit

Es ist aber sinnvoll, eine Grösse eines Views als 'int' auszulesen, weil diese in Pixeln angegeben ist (der Computer kann keine halben Pixel zeichnen!).

Die Typumwandlung passiert automatisch mit: "int width = ...".

grz ppocket
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
Es ist aber sinnvoll, eine Grösse eines Views als 'int' auszulesen, weil diese in Pixeln angegeben ist
Das ist falsch. Die Größe eines Views ist in „Points” angegeben. Die Umrechnung in Pixel geschieht erst beim Rendern auf das Ausgabemedium, was nicht nur der Bildschirm sein kann.

(der Computer kann keine halben Pixel zeichnen!).
Halbe Pixel nicht, Cocoa „simuliert” das dann aber durch unterschiedliche Helligkeiten.

MacApple
 

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
ja das ist mir auch schon aufgefallen, Danke für die Zahlreichen tipps
 

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
So ich grabe mal dieses Thema wieder aus, da ich nun wirklich Objective-C lernen will und alles.
Habe jetzt auch das Programm grundlegend neu geschrieben. Anstatt, dass ich in der DrawRect: Funktion das gesamte Fraktal berechne, mache ich das eben über eine NSBitmapImageRep und lasse diese nur in der DrawRect: an die View übergeben.
So nun habe ich auch noch andere Fragen:
erstens wie kann ich das angezeigte Bild speichern? Über die NSView, dem NSBitmapImageRep oder dem NSRect? Oder gibt es da eine ganz einfache Lösung, würde gerne das über den allgemeinen Speicherdialog machen wollen.
zweitens: Jedes mal, wenn ich das Bild neu berechne, wird der alte Speicher nicht freigegeben. Mit Instruments habe ich bis jetzt jedoch keine Leaks gefunden, es scheint mir so, dass das Bild, welches vor dem Berechnen da war, immer weiter im Speicher bleibt, kann ich dies irgendwie unterdrücken? oder wenigstens den Speicher wieder freigeben?
 

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
Hallo,

ein Bild kannst Du z.B. so sichern:

Code:
NSData *theImageData = [bliBlaBlubb TIFFRepresentation];
theImageData = [[NSBitmapImageRep imageRepWithData:theImageData] representationUsingType:NSPNGFileType properties:nil];        
[theImageData writeToFile:path atomically:YES];

Speichern > NSSavePanel

Memory > wir wissen nicht was Du geschrieben hast.

Viele Grüße
 

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
danke, leider muss ich den path noch erstellen und weiß nicht mit welchem Aufruf dies geschieht. (Hat sich erledigt -.- Stichwort NSSavePanel)

MyNSView.h:
Code:
#import <Cocoa/Cocoa.h>


@interface MyNSView : NSView {
    IBOutlet NSTextField *iBreelerAnteil;
    IBOutlet NSTextField *iBaufhellungM;
    IBOutlet NSTextField *iBaufhellungP;
    IBOutlet NSTextField *iBinterval;
    IBOutlet NSTextField *iBirreellerAnteil;
    IBOutlet NSTextField *iBiterationen;
    IBOutlet NSTextField *iBminX;
    IBOutlet NSTextField *iBminY;
    IBOutlet NSTextField *iBblau;
    IBOutlet NSTextField *iBgruen;
    IBOutlet NSTextField *iBrot;
	int iterationen,aufhellungsum,aufhellungfak,rot,gruen,blau;
	float reZo,imZo,reC,imC,zelle,minX,farbFaktor;

	NSBitmapImageRep *nsBitmapImageRepObj;
	NSRect nsRectFrameRect;
}
- (IBAction)JuliaFraktal:(NSButton *)sender;
- (IBAction)Standartwerte:(NSButton *)sender;  //Anpassung der Bildgröße
- (IBAction)Bsp1:(NSButton *)sender; //Setzten von Beispielswerten
- (IBAction)Bsp2:(NSButton *)sender;
- (IBAction)Fbsp1:(NSButton *)sender;
- (IBAction)Fbsp2:(NSButton *)sender;
- (IBAction)JuliaFraktal:(NSButton *)sender;
- (IBAction)Standartwerte:(NSButton *)sender;
- (IBAction)SavePicture:(NSMenuItem *)sender;

-(int)checkZo_reZ_minus1:(float)reZ_minus1 imZ_minus1:(float)imZ_minus1;
-(void)paintJulia;

@end

MyNSView.m:
Code:
#import "MyNSView.h"

@implementation MyNSView
- (IBAction)JuliaFraktal:(NSButton *)sender{
	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
	[nsBitmapImageRepObj release]; //Versuch Speicher wieder freizubekommen
	minX=[iBminX floatValue];
	aufhellungsum=[iBaufhellungP intValue];
	aufhellungfak=[iBaufhellungM intValue];
	rot=[iBrot intValue];
	gruen=[iBgruen intValue];
	blau=[iBblau intValue];
	nsBitmapImageRepObj=[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:[self bounds].size.width pixelsHigh:[self bounds].size.height bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO colorSpaceName:@"NSCalibratedRGBColorSpace" bytesPerRow:0 bitsPerPixel:0];
    [self paintJulia];
	[pool release];
}

- (IBAction)SavePicture:(NSMenuItem *)sender{
	NSData *theImageData = [nsBitmapImageRepObj TIFFRepresentation];
	theImageData = [[NSBitmapImageRep imageRepWithData:theImageData] representationUsingType:NSPNGFileType properties:nil];        
	[theImageData writeToFile:path atomically:YES];
}

-(id)initWithFrame:(NSRect)pFrameRect{   
    if(!(self=[super initWithFrame:pFrameRect])){
		NSLog(@"MyView initWithFrame *Error*");
		return self;
    }
	nsRectFrameRect=pFrameRect;
    return self;
}

-(int)checkZo_reZ_minus1:(float)reZ_minus1 imZ_minus1:(float)imZ_minus1{
	int i;
	float reZ,imZ;
	i=aufhellungsum;
	while(i<iterationen){
		i+=aufhellungfak;
		imZ=2*reZ_minus1*imZ_minus1+imC;
		reZ=reZ_minus1*reZ_minus1-imZ_minus1*imZ_minus1+reC;
		if((reZ*reZ+imZ*imZ)>4){
			return i;
			break;
		}
		reZ_minus1=reZ;
		imZ_minus1=imZ;
	}
	return i;
}

-(void)paintJulia{
	int x,y,iterationenZo;
	iterationen=[iBiterationen intValue];
	zelle=[iBinterval floatValue];
	reC=[iBreelerAnteil floatValue];
	imC=[iBirreellerAnteil floatValue];
	imZo=[iBminY floatValue];
	farbFaktor=100*iterationen;
	for(y=0;y<=[self bounds].size.height;y++){
		reZo=minX;
		for(x=0;x<=[self bounds].size.width;x++){
			iterationenZo=[self checkZo_reZ_minus1:reZo imZ_minus1:imZo];
			NSUInteger zColourAry[3]={round((rot*iterationenZo*255)/farbFaktor),round((gruen*iterationenZo*255)/farbFaktor),round((blau*iterationenZo*255)/farbFaktor)};
			[nsBitmapImageRepObj setPixel:zColourAry atX:x y:y];
			reZo+=zelle;
		}
		imZo+=zelle;
	}
	[self setNeedsDisplay:YES];
}
	
-(void)drawRect:(NSRect)pRect{
	[nsBitmapImageRepObj drawInRect:pRect];
}
@end

Mach das alles aus dem Grund in der View, weil ich finde, dass mit Controller und Model das hier einfach nicht gebraucht wird, dafür ist das Programm viel zu klein
 

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
Ich sage es direkt: Das ist falsch.

Das sind Aktionen, Eigenschaften usw. die haben da nichts verloren.

Egal wie groß oder klein die Applikation ist/wird, aber so ist es mit einer richtigen Umsetzung nicht aufwändiger.

Zumal Du Dir selbst ein Ei legst, da Du Dir selbst die Flexibilität entwendest.
Wie möchtest Du Dein Programm erweitern.

... ich erinnere Dich an Deine Aussage:

da ich nun wirklich Objective-C lernen will
Das ist nicht böse gemeint, aber lies doch bitte etwas über den Aufbau eine Applikation.

Viele Grüße
 
Zuletzt bearbeitet:

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
... noch etwas:

- Du schreibst Methoden groß
- Du arbeitest ohne Setter und Getter

... und das wichtigste:

- Du schreibst keine Kommentare

Ganz dringend z.B. Amin Negm-Awads Lektüre lesen. (Meine persönliche Empfehlung)

Viele Grüße
 

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
so nun habe ich folgendes Problem:
Das Bild wird im Model richtig berechnet (habe das mit stdio.h und printf nachgeprüft), nun aber schaffe ich es nicht, das Bild in die View zu bekommen

Code:
MyModel.m

-(id)getBitmap{
	return nsBitmapImageRepObj;
}

MyView.m

- (void)drawRect:(NSRect)pRect {
    [[myModel getBitmap] drawInRect:pRect];
}

Muss ich da noch was zusätzlich machen? Also ich noch alles in der view-class gemacht habe, reichte es ja einfach die NSBitmapImageRep in das rect zu zeichnen, wenn ich jetzt jedoch von der View-class das NSBitmapImageRep aus der Model-class hole wird in der NSVIew nichts angezeigt, obowhl ich eben genau weiß, dass die Daten in der NSBitmapImageRep richtig sind
 

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
Code:
- (void)drawRect:(NSRect)pRect {
    [[myModel getBitmap] drawInRect:pRect];
}
Du kommunizierst nicht von dem View aus nach oben.
Das ist nicht dessen Aufgabe.

Du benötigst ein Outlet.
Anbei ein Beispiel.

Code:
-(id)getBitmap{
    return nsBitmapImageRepObj;
}
Wenn das ein Getter repräsentiert, dann müsste das z.B. so lauten:

Code:
-(NSimage*)calcImage{
    return calcImage;
}
Eine Instanzvariable hat in der Regel einen zugänlichen Setter und Getter.
Dabei sind auf besonders Cocoa/Object-C sprachliche Formen zu achten.

Das fiel mir am Anfang auch schwer. Ist aber ein tolles System.
Get hat da aber nichts zu suchen. ;)

Ich persönlich würde Dir auch schwer von "id" abraten.
Diese werden nur in besonderen Fällen verwendet aber nicht als Standard.
Da kannst Du in äußerst böse Sachen laufen.
Profis können Dir da sicherlich einiges zu erzählen.

Viele Grüße
 

Anhänge

  • SomeSample.zip
    56 KB · Aufrufe: 50

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
ah jetzt weiß ich was ich da immer vergessen habe :D das "*", ne ich benutze ehh so selten wie möglich id, habe auch die gesamten Outlets von id z.b. in NSButton geändert.

Aber es lag an was anderem, warum es nicht ging.

Code:
MyController.m

[myModel initBitmapWithWidth:[myView bounds].size.width Height:[myView bounds].size.height];
also war die NSBitmapImageRep doch noch nicht initialisiert, naja egal, es geht jetzt auf jedenfall irgendwie (auch wenn etwas langsamer als vorher).

Und das mit dem aus der View hinaus kommunizieren, also ich hatte was gelesen und naja soweit ich es verstanden habe, dient der Controller dazu Aufgaben zu verteilen und auf Zugriffe auf die GUI entsprechend zu regieren, das Model dient dazu Aufgaben zu bearbeiten und die Daten über Ergebnisse abzuspeichern sozusagen ein Datenspeicher, und die View ist dazu da, die Daten aus dem Model irgendwie anzuzeigen. Dürfte dann die View nicht mit dem Model kommunizieren um eben die anzuzeigenden Daten zu bekommen oder muss ich das andersherum machen?

Naja ich gucke mir mal das Beispiel an und guck was ich noch verkehrt denke...

aber danke für die Antworten schonmal
 

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
Diese Regelungen lassen sich nicht immer in allen Fällen anwenden.
Ab und an muss man ein Verbrechen begehen.

In Deinem Fall sehe ich aber kein Grund, weshalb sich Dein View-Element um die Daten kümmern sollte.
Somit ist ein Vergehen hier nicht legitim ;)

Lade doch mal Dein Projekt hoch.
Dann kann man sehen was Du baust und zielgerichteter antworten.

Viele Grüße
 

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
so, das Programm sollte an sich gehen...
 

Anhänge

  • Julia-Fraktal.zip
    61 KB · Aufrufe: 54

karolherbst

Danziger Kant
Registriert
11.05.07
Beiträge
3.878
so habe nun Speicherfunktionen und noch alles eingebaut. Nur jetzt ist die Frage: wie kann ich aus dem Programm-Paket aus dem Resource-Ordner eine Bilddatei in eine View reinladen? Bin jetzt soweit, dass ich nur noch eine zum Programm relative Pfadangabe brauche, also "???/Contents/Resources/Bild.png"
 

LittlePixel

Strauwalds neue Goldparmäne
Registriert
09.07.08
Beiträge
641
Du brauchst primär keine Pfadangaben für Deine eigene Applikation.
Warum alles neu erfinden?

Einfacher geht es mit:

Code:
// Lade von meinem Bundle
NSImage *blubbImage = [NSImage imageNamed:@"ImageNameWihoutFileExtension"];

Viele Grüße
 
  • Like
Reaktionen: karolherbst