1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

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

Dieses Thema im Forum "OS X-Developer" wurde erstellt von karolherbst, 01.01.09.

  1. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    Code:
    -(void)paint{
    	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    	NSBezierPath *Path=[NSBezierPath bezierPath];
    	[Path moveToPoint:NSMakePoint(x, y)];
    	[Path lineToPoint:NSMakePoint(x, y+1)];
    	[[NSColor colorWithCalibratedRed:red*iterationenZo/Farbtiefe green:green*iterationenZo/Farbtiefe blue:blue*iterationenZo/Farbtiefe alpha:1] setStroke];
    	[Path stroke];
    	[pool release];
    }
    wenn ich diese Methode über
    Code:
    -(void)drawRect:(NSRect)rect{...
    [self paint];
    ...}
    aufrufe, dann wird mir das Ergebnis beim Start des Programmes wunderbar angezeigt, wenn ich jetzt aber die Methode auf
    Code:
    -(void)JuliaMenge:(id)sender{...}
    umschreibe, rechnet das Programm zwar alles richtig aus, zeigt aber das "entstehende" Bild nicht an.
    Habe mir überlegt, dass es daran liegen könnte, dass kein Rechteck vorliegt als Objekt, also was kann ich machen?

    PS: Ja ich weiß per Bitmap ist das schöner zu machen, aber ich will ja ObjC lernen und versuche das mit verschiedenen Möglichkeiten zu realisieren.
     
  2. Bief

    Bief Weigelts Zinszahler (Rotfranch)

    Dabei seit:
    11.12.06
    Beiträge:
    249
    Sehe ich richtig, dass du in JuliaMenge: die drawRect-Funktion von dem View aufrufst?

    Probier mal [self setNeedsDisplay:YES];
    dann ruft die View automatisch die drawRect: - Function auf.
     
    karolherbst gefällt das.
  3. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    mhhh -(void)drawRect: (NSRect)rect und -(void)JuliaMenge: (id)sender sind die gleiche Methode, nur eben das drawRect beim Programmstart schon ausgeführt wird und JuliaMenge erst beim Knopfdruck,

    das mit dem [self setNeedsDisplay:YES]; klappt irgendwie nicht oder ich setze es an die falsche Position :D also ich bin neuling und das ist erst mein ersten Programm, aber ich denke mal, dass das mit der Speicherverwaltung auch so richtig ist oder?
     
  4. Bief

    Bief Weigelts Zinszahler (Rotfranch)

    Dabei seit:
    11.12.06
    Beiträge:
    249
    Da versteh ich auch nicht, warum den NSAutoReleasePool benutzt... Ich bin eigentlich auch Anfänger, hab aber schon einiges mit den Views gemacht (und noch nie NSAutoReleasePool benutzt ;))...

    Bei deinem NSColor-Aufruf blick ich leider auch gar nicht durch ;). Das hab ich so bisher nie gemacht... Ich hab das immer z.B. über [[NSColor greenColor] set] gemacht... Aber es scheint ja beim Start zu funktionieren ;)

    Ich würde dir auf jeden Fall empfehlen, auf nen Pro hier zu warten der dir hilft und es ist auf jeden Fall eleganter, wenn du in die JuliaMenge: [self setNeedsDisplay:YES] einfügst. Du kannst ja mal mit einem NSLog schauen, ob die drawRect:-Funktion dann aufgerufen wird...
     
  5. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    ähhhm mein Programm erstellt eine Julia-Menge,
    colorWithCalibratedRed: gree: blue: alpha: ist eine Methode um die Farbe anzugeben, also jede beliebiege, es werden hierbei float-Werte verwendet.
    bei Red:red*iterationenZo/Farbtiefe ist red der relative Farbanteil, damit man bisschen mischen kann und so, iterationenZo, ist eine Variable, die durch die Fukntion Ieratuon gefüllt wird, da wird ein WErt zwischen 1 und 100 ausgegeben. Farbtiefe ist die Grenze der Funktion also in dem Fall 100. Dabei entsteht ein Fraktalbild (Habe ich hier angehängt). Und ich habe NSAutoReleasePool verwenden, weil dann das Programm anstatt 30MB nur noch 8MB RAM verbraucht, und cih finde, dass ist schon Grund genug, da ich mal einen Test auf 1680*1050 Pixeln gemacht habe und da kam er schon auf ca 120MB

    EDIT: nach nem Klick aufm Knopf, bleibt der erstmal ne Zeit lang blau (Knopf wird im Bild nicht angezeigt, doof), also denke ich, dass der da richtig am Rechnen ist, Aktivitätsanzeige zeigt auch 100% Auslastung an.
     

    Anhänge:

    #5 karolherbst, 01.01.09
    Zuletzt bearbeitet: 01.01.09
  6. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Du kannst nicht einfach drauf los zeichnen, sondern nur in -drawRect:.Das liegt daran, dass vor dem Aufruf von -drawRect: verschiedene Vorarbeiten gemacht werden. Außerdem entscheidet die View-Ebene, wann ein Update erforderlich ist.

    Lies mal etwas zu MVC. Das ist völlig der falsche Ansatz.
     
  7. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    *seufz* schon wieder jmd, der nur sagt, was ich falsch mache und nicht sagt, wie ich es bitte richtig machen soll. Natürlich ist das der falsche Ansatz, weil man das Programm eigentlich nur über ne BitMap schrieben sollte. Und weiter ist das ja eigentlich richtig, da er ja die ganzen Sachen berechnet, aber nicht anzeigt, ich will ja nur wissen, wie ich die drawRect Methode aufrufen kann, damit das Programm die Rechtecke zeichnet.

    EDIT: Ich hasse es so Dinger durchzulesen, ich brauche nur wissen, wie ich Methoden schreibe, Objekte deklariere und so weiter, mehr brauche ich nicht, um schnelle flotte Programme zu schreiben, und ja das mit diesem AutoreleasePool war ne Sachen von ner Minute um das zu verstehen.
     
  8. Bief

    Bief Weigelts Zinszahler (Rotfranch)

    Dabei seit:
    11.12.06
    Beiträge:
    249
    OK, interessant, danke :). Soweit war ich in meinem Buch wohl noch nicht :p
     
  9. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    *seufz* Ich hasse Leute, die mir nur sagen, wie ich falsch helfe.

    Nein, es bringt dir gar nichts, dass man dir die Methode schreibt. Dann wartet nämlich das nächste Problem an der nächsten Ecke.

    Aber mein Gott, wenn du mit ner Hilti in deinem Gebiss herumfrickeln willst, mach es halt. Es ist dein Gebiss.
     
  10. Jamsven

    Jamsven London Pepping

    Dabei seit:
    21.11.07
    Beiträge:
    2.046
    Genau das macht ein schlechter Programmierer. Alleine "schnell und flott" beisst sich mit deiner Arbeitsweise. Es ist wichtig Hintergrundwissen zu besitzen, sonst kannst schnell mal beispielsweise auf einer falschen Datenstruktur setzten, die sich später als Flaschenhals entpuppt.
     
  11. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    jaa hast schon Recht, ich weiß ja auch, dass die drawRect Methode immer dann aufgerufen wird, wenn das "Bild" neuaufgebaut werden muss, beim Scrollen zb oder wenn man was drüber schiebt, irgendsowas halt, bei meinem Programm wurde die DrawRect methode beim Start zwar aufgerufen, hat auch alles gezeichnet und so weiter, jedoch hat die sich nachm fertigem Abruf neu aufgerufen, dass hat mcih irritiert, weil ich nicht wusste warum er das Bild neuaufbauen muss, jetzt habe ich gerade bemerkt, dass die Umrandung vom Button, diese leuchten in das "Bild" reinging, habe das behoben und nun geht das auch irgendwie... habe jetzt auch die "mal befehle" in die drawRect Methode reingeschoben, und der Knopf ruft beim aktivieren die drawRect Methode auf, ich weiß nicht was ihr davon haltet, aber nun ja, läuft bis jetzt alles gut, außer das eben das das neue rect nicht angezeigt wird,.
     
  12. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Die drawRect: Methode ruft man nicht selbst auf, sondern lässt das System das machen. Grund: Das System bereitet den Grafikkontext entsprechend vor. Ist der Grafikkontext nicht richtig vorbereitet, bekommst Du nicht das erwartete Ergebnis. Benutze Cocoa so, wie es Apple vorgesehen hat. Dann funktioniert das auch.
    Wenn Du dem System sagen willst, dass Dein View neu gezeichnet werden muss, dann sende Deinem View die Nachricht setNeedsDisplay: mit dem Parameter-Wert YES. Dann wird die drawRect: Methode vom System auch aufgerufen.
    Mehr zum Zeichnen mit Cocoa wird hier erklärt.

    MacApple
     
    karolherbst gefällt das.
  13. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    jaa, habs endlich rausbekommen :D der Tipp mit [self setNeedsDisplay:YES]; hätte ich weiter befolgen müssen, danke an Bief nochmals. Das einzige was mich gestört hat, ist dass sich die DrawRect Methode sogutwie immer aufgerufen hat, also echt immer, habe in sie jetzt eine if-Schleife gelegt, damit die CPU-Auslastung nicht permanent auf 100% liegt (ja klingt doof, aber lässt sich glaube ich nichts dran ändern), Nachteil ist, dass beim Verändern der Fenstergröße der Inhalt komplett gelöscht wird, (Aufbau von 400*300 Pixel dauert bei mir schon ca. 10 Sekunden, also zum Thema permanent DrawRect und CPU-Auslastung) habe jetzt auch schon mehrere Textfelder eingerichtet um die Farbe, reellen Anteil, irriellen Anteil der Julia-Menge u verändern usw. Jetzt mein Problem: er ändert die Werte nur, wenn ich die Felder wieder "verlasse" Code:
    Code:
    -(IBAction)changeWidth:(id)sender{
    	width=[sender floatValue];
    }
    oder gibt es einen eleganteren Weg, Werte aus dem GUI rauszuholen?
     
  14. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Doch, da lässt sich was dran ändern, in dem man den Ansatz richtig wählt. Da kann ich nur wie Amin raten, Dich mit dem MVC (Model-View-Controller) Paradigma zu beschäftigen. MVC wird in Cocoa konsequent durchgezogen. Du arbeitest dagegen an (machst alles im View) und deshalb hast Du diese Probleme.

    Weil Du alles im View machst. Das ist nicht „the Cocoa way”!

    Nein, das ist der richtige Weg. Dein Problem wird vermutlich sein, dass der zuletzt geänderte Wert vor der neuen Berechnung nicht übernommen wird. Das kannst Du erzwingen, in dem Du vor der neuen Berechnung dem Textfeld den First Responder Status entziehst:
    Code:
    [deinFenster makeFirstResponder:deinFenster];
    MacApple
     
  15. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    also der Wert wird nur dann übernommen, wenn ich zuvor das TextFeld verlassen habe, also der Fokus zu einem anderen Objekt springt, also bräuchte ich ne Möglichkeit, wo der Wert schon beim Eingeben übergeben wird, oder halt erst beim Aufruf der drawRect: Methode
     
  16. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Hast Du meinen Beitrag auch bis zum Ende gelesen?

    MacApple
     
  17. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    asooo, klar, hatte was falsch gemacht, jo klappt, danke, wenn ich das mit dem MVC richtig verstanden habe, dann speichert er sozusagen die Ausgabe in dem Controller ab und zeigt sie dann ohne großartige Berechnungen im View, oder?

    EDIT: ähhh ich habe vergessen wie sich ein Programm durch das schließen des Fensters beendet :D
     
    #17 karolherbst, 03.01.09
    Zuletzt bearbeitet: 03.01.09
  18. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Da in deinem Beitrag nur View und Controller vorkommen,kann das irgendwie noch nicht MVC sein.

    Aber für kleine Sachen kann man mal Controller und Model zusammenwerfen.
     
  19. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    jo ist nur ganz klein, der rechnet aucc nur ca Höhe*Breite*255 mal eine bestimmte Funktion, das soll nur was ganz simples werden, falls du dich mit der Julia-Menge auskennst, wirst du verstehen was ich meine.
     
  20. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Ich verstehe deine Problemlösung schon. Geht es dir um diese Funktionalität an sich, kann man das wie gesagt so machen.

    Geht es dir aber um eine Einführung in die Programmiererei unter Cocoa, solltest du es zumindest einmal richtig probieren. man kann von Konzepten schon einmal abweichen. Vorher sollte man die Konzepte aber verstanden haben.
     

Diese Seite empfehlen