#035 Cheddar: Delegates und Timer
(66:01 Minuten)
Hilfsmittel sind dabei selbstgeschriebene Delegates, dynamische Methodenaufrufe anhand von Selektoren und eine neue Cocoa-Klasse: NSTimer.
Und wer nicht weiss, wovon wir reden, es aber erfahren möchte, der sollte diese Mammutfolge anschauen...!
Delegates hatten wir übrigens auch schon in diesen Folgen erklärt:
Selektoren erklären wir unter Anderem in der Folge #031 Cheddar: Threading, wo wir einen Selektor zum Starten des Threads benutzen.
Ihr bekommt den Quellcode zu dieser Folge in unserem SVN-Repository direkt aus Xcode heraus unter "releases/episode_035", oder am Terminal mit:
svn checkout https://cheddar1.svn.sourceforge.net/svnroot/cheddar1/releases/episode_035
13 Kommentare
|
Permalink
|
Trackback-Info
|
Film in HD ansehen!
Kommentar hinzufügen
13. Unbedeutender Kommentator am 25. Mar 2010, 00:22 Uhr
@ingo:
Nochmal zum Thema id vs. NSObject. Dass der Compiler bei id nicht die Methodennamen checkt, ist eine sehr schwache Ausrede. Erstens checkt der Compiler natürlich auch bei id die Methodennamen und zweitens umgeht Ihr diesen Check sowieso durch die Verwendung von performSelector... Methoden.
@ingo:
Nochmal zum Thema id vs. NSObject. Dass der Compiler bei id nicht die Methodennamen checkt, ist eine sehr schwache Ausrede. Erstens checkt der Compiler natürlich auch bei id die Methodennamen und zweitens umgeht Ihr diesen Check sowieso durch die Verwendung von performSelector... Methoden.
12. Bastian am 24. Mar 2010, 19:03 Uhr
@Pennywise Nachteil an int* anIntPtr ist, dass folgendes Statement
int* anIntPtr, anInt;
impliziert, dass man zwei Int-Pointer allokiert, wobei man in Wirklichkeit ein Int und ein Int-Pointer allokiert. Das Statement ist also äquivalent zu:
int anInt, *anIntPtr;
Logisch gehört der Stern also zum Variablenname und nicht zum Typ. (Diese Problematik ist allerdings eher C im Allgemeinen anzulasten als unseren Podcastern oder dem großen Apfel)
Stimmt schon, in der GUI-Programmierung kommt das eher nicht zum Einsatz, aber ich arbeite zum Beispiel gerade an einem Programm, das Core Audio benutzt und da gehts wieder heiß her mit Typecasting und Pointer-gewedel.
@Pennywise Nachteil an int* anIntPtr ist, dass folgendes Statement
int* anIntPtr, anInt;
impliziert, dass man zwei Int-Pointer allokiert, wobei man in Wirklichkeit ein Int und ein Int-Pointer allokiert. Das Statement ist also äquivalent zu:
int anInt, *anIntPtr;
Logisch gehört der Stern also zum Variablenname und nicht zum Typ. (Diese Problematik ist allerdings eher C im Allgemeinen anzulasten als unseren Podcastern oder dem großen Apfel)
Stimmt schon, in der GUI-Programmierung kommt das eher nicht zum Einsatz, aber ich arbeite zum Beispiel gerade an einem Programm, das Core Audio benutzt und da gehts wieder heiß her mit Typecasting und Pointer-gewedel.
11. Pennywise81 am 24. Mar 2010, 08:39 Uhr
@jemand:
int-Pointer sind nichts Außergewöhnliches. Dahinter muss sich nicht zwingend ein Objekt befinden, sondern vielleicht ein C-Array oder eine Referenz auf eine Variable.
Oder man steppt einfach durch den Speicher.
Allerdings ist sowas bei High-Level-GUI-Programmierung eher selten im Einsatz.
Ansonsten kann ich Bastians Kritik nur beipflichten. Man sollte schon versuchen eine einheitliche Schreibweise zu verwenden, wobei das jetzt auch kein Killerkriterium ist. Ich wäre allerdings eher für die Schreibweise int* aIntPointer, was aber wohl eher an meiner Gewohnheit und der Coding-Guideline auf meiner Arbeit liegt ;)
@jemand:
int-Pointer sind nichts Außergewöhnliches. Dahinter muss sich nicht zwingend ein Objekt befinden, sondern vielleicht ein C-Array oder eine Referenz auf eine Variable.
Oder man steppt einfach durch den Speicher.
Allerdings ist sowas bei High-Level-GUI-Programmierung eher selten im Einsatz.
Ansonsten kann ich Bastians Kritik nur beipflichten. Man sollte schon versuchen eine einheitliche Schreibweise zu verwenden, wobei das jetzt auch kein Killerkriterium ist. Ich wäre allerdings eher für die Schreibweise int* aIntPointer, was aber wohl eher an meiner Gewohnheit und der Coding-Guideline auf meiner Arbeit liegt ;)
9. Bastian Bechtold am 23. Mar 2010, 15:03 Uhr
Super Podcast, den ihr da macht!
Aber eine Sache stört mich schon ganz lange: Mal schreibt ihr
NSTextField* aTextField; // oder auch:
NSTextField *aTextField; // oder sogar:
NSTextField * aTextField;
Ich weiß, das sind Kleinigkeiten, aber es macht den Code unübersichtlicher. Ich persönlich bin für
NSTextField *aTextField;
Weil der Stern nur für die eine Variable gilt und somit folgender Ausdruck mehr Sinn macht
int *anIntPtr, anInt;
Liebe Grüße,
Basti
Super Podcast, den ihr da macht!
Aber eine Sache stört mich schon ganz lange: Mal schreibt ihr
NSTextField* aTextField; // oder auch:
NSTextField *aTextField; // oder sogar:
NSTextField * aTextField;
Ich weiß, das sind Kleinigkeiten, aber es macht den Code unübersichtlicher. Ich persönlich bin für
NSTextField *aTextField;
Weil der Stern nur für die eine Variable gilt und somit folgender Ausdruck mehr Sinn macht
int *anIntPtr, anInt;
Liebe Grüße,
Basti
8. Jixxwar am 22. Mar 2010, 18:40 Uhr
Die Details sind Nebensache. Ist doch eine super Folge! Muss sagen, seit langem sogar die beste Folge. Zumindest aus meinem Blickwinkel. :)
Die Details sind Nebensache. Ist doch eine super Folge! Muss sagen, seit langem sogar die beste Folge. Zumindest aus meinem Blickwinkel. :)
7. ingo am 22. Mar 2010, 15:04 Uhr
@Jixxwar:
1. Keine Ahnung. :) Wir hätten natürlich auch den sender nehmen können. Der ist wiederum bei den Methoden im SyncManager selbst komplett überflüssig. Aber so kann es nunmal trotz nebenliegendem Skript passieren, wenn man live aufnimmt und auf viel zu viele Dinge achten muss... ;-)
2. Jepp, so eine Klassenmethode kann man natürlich schreiben
3. Der Timer läuft ebenfalls im MainThread. Solange der eigene MainThread einen Event oder eine Methode ausführt wird definitiv kein Timer abgefeuert. Ein Timer stellt also nicht automatisch sicher, dass er immer pünktlich aufgerufen wird.
@Raphael:
Jepp, das wäre ordentlicher ;)
Allgemein:
Die Folge ist schon ziemlich lang und wir hatten echt ein Zeitproblem. Wir haben also alles auf das grundsätzliche Thema runtergekürzt, dass wir verstanden wissen wollten.
@Jixxwar:
1. Keine Ahnung. :) Wir hätten natürlich auch den sender nehmen können. Der ist wiederum bei den Methoden im SyncManager selbst komplett überflüssig. Aber so kann es nunmal trotz nebenliegendem Skript passieren, wenn man live aufnimmt und auf viel zu viele Dinge achten muss... ;-)
2. Jepp, so eine Klassenmethode kann man natürlich schreiben
3. Der Timer läuft ebenfalls im MainThread. Solange der eigene MainThread einen Event oder eine Methode ausführt wird definitiv kein Timer abgefeuert. Ein Timer stellt also nicht automatisch sicher, dass er immer pünktlich aufgerufen wird.
@Raphael:
Jepp, das wäre ordentlicher ;)
Allgemein:
Die Folge ist schon ziemlich lang und wir hatten echt ein Zeitproblem. Wir haben also alles auf das grundsätzliche Thema runtergekürzt, dass wir verstanden wissen wollten.
6. Raphael am 22. Mar 2010, 14:55 Uhr
Jungs, schöne Folge! Kurzes Feedback:
(Gerade gesehen, dass auf "id" und "@protocol" bereits eingegangen wurde, deshalb lösche ich diese Punkte mal wieder, das folgende gilt aber auch für die aktuelle Umsetzung.)
- Im dealloc vom Table Controller wäre es schön, wenn wir schauen ob die Delegate Property vom Sync Manager uns selbst (self) entspricht und wenn ja auf nil setzten, wenn wir selber weggehen.
Gruss, Raphael
Jungs, schöne Folge! Kurzes Feedback:
(Gerade gesehen, dass auf "id" und "@protocol" bereits eingegangen wurde, deshalb lösche ich diese Punkte mal wieder, das folgende gilt aber auch für die aktuelle Umsetzung.)
- Im dealloc vom Table Controller wäre es schön, wenn wir schauen ob die Delegate Property vom Sync Manager uns selbst (self) entspricht und wenn ja auf nil setzten, wenn wir selber weggehen.
Gruss, Raphael
5. Jixxwar am 22. Mar 2010, 14:24 Uhr
Huhu, sehr schöne Folge. Vielen Dank, auch für den wunderbaren Buchtipp. Kannte das Buch noch gar nicht, Hellgrün ist auch sehr schön.
Nur einige Punkte:
- In den neuen Delegate Methoden des im ViewController, warum wird hier der "self.syncManager.files" für den Zugriff auf die Files Dict verwendet und nicht die übergebene "sender" Variable?
- Kann man das Delegate für den SyncManager nicht direkt beim Erstellen anlegen. Also z.B. [SyncManager syncManagerWithDelegate:self]; ?
+(id)syncManagerWithDelegate:(NSObject*)newDelegate { ... }
- Sollte man den NSTimer nicht vor dem endgültigen Statusupdate, damit es nicht passieren kann, dass die 'ing Form zum Schluss darsteht? (Nochmalige ausführung des Timers, zwischen Textset und Timerkill)
mfg.
Dominic
Huhu, sehr schöne Folge. Vielen Dank, auch für den wunderbaren Buchtipp. Kannte das Buch noch gar nicht, Hellgrün ist auch sehr schön.
Nur einige Punkte:
- In den neuen Delegate Methoden des im ViewController, warum wird hier der "self.syncManager.files" für den Zugriff auf die Files Dict verwendet und nicht die übergebene "sender" Variable?
- Kann man das Delegate für den SyncManager nicht direkt beim Erstellen anlegen. Also z.B. [SyncManager syncManagerWithDelegate:self]; ?
+(id)syncManagerWithDelegate:(NSObject*)newDelegate { ... }
- Sollte man den NSTimer nicht vor dem endgültigen Statusupdate, damit es nicht passieren kann, dass die 'ing Form zum Schluss darsteht? (Nochmalige ausführung des Timers, zwischen Textset und Timerkill)
mfg.
Dominic
4. ingo am 21. Mar 2010, 23:45 Uhr
Wie man eigene Protokolle erstellt, wird von uns noch erklärt werden. Uns ist zunächst mal wichtig, dass man das grundlegende Prinzip versteht. Zudem können wir leider nicht alles auf einmal machen...speziell von NSProxy sind wir noch eine Folgenanzahl im 2stelligen Bereich entfernt ;)
Apple nutzt im Übrigen erst seit dem iPhone und Leopard ernsthaft Protokolle und intensiviert das mit Snow Leopard deutlich - und ich gehe mit Dir konform, dass das definitiv ein wichtiger Schritt ist.
Wie man eigene Protokolle erstellt, wird von uns noch erklärt werden. Uns ist zunächst mal wichtig, dass man das grundlegende Prinzip versteht. Zudem können wir leider nicht alles auf einmal machen...speziell von NSProxy sind wir noch eine Folgenanzahl im 2stelligen Bereich entfernt ;)
Apple nutzt im Übrigen erst seit dem iPhone und Leopard ernsthaft Protokolle und intensiviert das mit Snow Leopard deutlich - und ich gehe mit Dir konform, dass das definitiv ein wichtiger Schritt ist.
3. Wursthaut am 21. Mar 2010, 23:30 Uhr
> Eigentlich sollte unter Cocoa alles von NSObject ableiten
Nö, siehe NSProxy!
Das das Ganze mit NSObject wunderbar funktioniert ist klar.
Der Beste Weg das Ganze zu realisieren, ist aber wahrscheinlich der mit Hilfe eines Protokolls (so wie es Apple auch macht).
Bsp.: NSTableView:
- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
> Eigentlich sollte unter Cocoa alles von NSObject ableiten
Nö, siehe NSProxy!
Das das Ganze mit NSObject wunderbar funktioniert ist klar.
Der Beste Weg das Ganze zu realisieren, ist aber wahrscheinlich der mit Hilfe eines Protokolls (so wie es Apple auch macht).
Bsp.: NSTableView:
- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
2. ingo am 21. Mar 2010, 22:14 Uhr
Eigentlich sollte unter Cocoa alles von NSObject ableiten. Sonst hat man keinerlei Methoden für Speichermanagement oder gar performSelector-Methoden.
Natürlich kann man auch id nehmen, aber da checkt z.B. der Compiler nicht mehr, wenn man sich bei Methodennamen vertippt.
Eigentlich sollte unter Cocoa alles von NSObject ableiten. Sonst hat man keinerlei Methoden für Speichermanagement oder gar performSelector-Methoden.
Natürlich kann man auch id nehmen, aber da checkt z.B. der Compiler nicht mehr, wenn man sich bei Methodennamen vertippt.
1. Wursthaut am 21. Mar 2010, 19:06 Uhr
Warum verwendet ihr statt id NSObject bei der Deklaration des Delegate-Pointers? (Hintergrund: Klassen müssen nicht unbedingt Abkömmlinge von NSObject sein.)
Warum verwendet ihr statt id NSObject bei der Deklaration des Delegate-Pointers? (Hintergrund: Klassen müssen nicht unbedingt Abkömmlinge von NSObject sein.)