Erstes Cocoa Heads Berlin Meeting

written by Martin Häcker on

So, gegründet ist sie also die CocoaHeads Chapter Berlin. Und Lustig wars auch - immerhin doch 15 Cocoa-Programmierer, die meisten davon überraschenderweise fürs iPhone. Und auch eine Menge Leute die mann schon kennt.

Der Entwickler von Aurora, AppFresh und Fahrinfo Berlin war da (der überraschenderweise in Potsdam immer noch studiert!), der Entwickler von GarageSale, einige Leute aus der iPhone-Abteilung von Neofonie und natürlich der Gründer und noch einige Freelancer und andere Gesellen bei denen ich mich nicht mehr an die Applikationen erinnern kann.

Also ein ganz hervorragender Start für ein Kakaokopftreffen. :)

Obamas elektronischer Wahlsieg

written by Martin Häcker on

Vor ein paar Tagen hat mir ein Bekannter ganz begeistert davon erzählt, wie sehr Obama gewonnen hätte, weil er das Internet endlich richtig benutzt.

Erstaunlicherweise habe ich davon sehr wenig mitbekommen - daher war ich etwas skeptisch. Jetzt habe ich einen ganz hervorragenden Bericht von meinem Bekannten Wolfgang Goede gelesen - der in Amerika als Wahlhelfer gearbeitet hat, um die Wahl und ihre Ergebnisse besser zu verstehen.

Ich bin persönlich ja der Meinung dass seine Fähigkeiten als Community-Organizer weit mehr mit dem Wahlsieg zu tun haben als mein Bekannter dachte - aber er hat tatsächlich viele dinge Online gemacht.

Und will das auch weiter tun.

Das finde ich großartig.

Apple iPhone Tech-Talk

written by Martin Häcker on

War ja ganz nett auf den Apple iPhone TechTalks - alles zusammen allerdings etwas langweilig weil wenig in die Tiefe. :-(

Lustiges Detail am Rande: Zwar war die Veranstaltung mit Anmeldung und schon lange vorher ausgebucht - aber trotzdem kam man vor Ort noch gut rein - das nächste mal kann man es also auch ohne Anmeldung einfach mal versuchen.

Interessant auch, dass das ganze Event unter NDA stand, das heißt, obwohl ich dort war und nur Informationen verbreitet wurden die alle ohne NDA aus der API erhältlich waren, darf ich nicht darüber erzählen was es dort zu hören gab. Das fand ich so strange dass ich doch gleich einen der Vortragenden Apple-Mitarbeiter gefragt habe wie das zu verstehen ist: Dieser hat sich dann entschuldigt und bestätigt, dass natürlich alle Informationen die aus den APIs kommen frei bloggbar sind, aber eben nicht worüber auf dem Event darüber gesprochen wurde.

Schade eigentlich.

iPhone Applicaton Development

written by Martin Häcker on

Hier einige Notizen zu der iPhone API die ich spannend finde:

iPhone Development Facts

  • iPhones in 70 Ländern mit 70+ millionen iPhones (plus unbekannt viele Touches)
  • 5500 Apps gibts im App Store
  • 200 Millionen Apps wurden in 121 Tagen vergekauft
  • Wie Funktionieren iPhone Applikationen:
    • Bedienung mit dem Finger und Gesten: Pinch, Flick
    • So wenig Input wie möglich machen (Weil Input anstrengend ist)
    • Wenig Platz auf dem Bildschirm: Jede Applikation macht eine Sache und nur die
    • GPS, Accelerometer werden benutzen
    • Wenn die Applikation beendet wird wird der Zustand gesichert
  • Kriterien für Erfolgreiche Apps:
    • Delightfull (Spaß, Intuitiv)
    • Innovative (Revolutionär, Innovativ, anspruchsvolle Technik)
    • Designed
      • Great Design -> kleine Teams damit gute Ideen auch eine Chance haben
      • viele Iterationen
      • ständiger Fokus auf Design [40% der Zeit! Nicht wie sonst]
      • Attention To Detail
      • "Sollutions Not Features"
      • "Saying no to 1000 things"
      • "Chose top 5 Features and amplify them"
      • "Flatten data, to make it easily digestible"
      • 30 Second usage Scenario: Man soll nach 30 Sekunden mit der Applikation schon wieder fertig sein.
    • Integratied (Use all available technology - don't reinvent)
    • Optimized (Performance, Stability, Battery Life is important), no PORT -> neu und spezifisch fürs iPhone bauen
    • Connected: Integrate data as much as possible, Connect to a Mac-Application
    • Localized (40% des Maktes sind nicht-Englisch) Applikation UND Store lokalisieren! (Sonst weiß kein User dass die Applikation lokalisiert ist)
    • Diese Checkliste immer wieder abarbeiten. :)

Dev Tools Overview

  • Platz sparen ist das wichtigste, da sonst der watchdog das Programm killt
  • Ein iPhone Programm sollte nur etwa 20-25 MB Ram benutzen (Insbesondere nicht so viel wie direkt nach dem Start des iPhones frei ist!)
  • Code: Alles statisch gelinkt -> Code wird man nicht los
  • Bilder: png! (evtl. nochmal speziell komprimieren)
  • Named-Images: Die sind immer im Speicher da gecached -> Durch Filename laden (wird dann nicht gecached)
  • Audio: Dolby Surround ist schlecht -> mp3, mp4
  • Caching darf man gerne selber implementieren - Flasch kann man so viel nutzen wie man will
  • Applikationen im App-Store können maximal 2 Gig groß sein.

User Interface Design

Eine Applikation zu erstellen kann man grob in 4 Phasen einteilen

  • Familiarize:
    • iPhone verstehen
    • HIG lesen
    • Je schnell man mit einer Applikation fertig ist, desto besser: Starbucks, während jemand vor einem was ordert! (<30 sek)
    • Schnell starten / laden, schnell etwas rausfinden, schnell wieder beenden
    • Andere Input-Art: Finger. Weniger Input ist mehr!
      • Nach Möglichkeiten suchen Tippen zu vermeiden - weil schwer
      • Tippfehler akzeptieren / korrigieren
    • Weniger Platz am Bildschirm: Das wichtigste aussuchen, das Verstärken
      • "Reduce and Amplify!"
      • "You want to strip this app to the bone!"
  • Conceptualize
    • Fokus auf Lösungen!
    • "Refine, Refine, Refine"
    • Das Mentale Modell der User ergründen
      • Eine Frau die Kinder, Hund, Mann pflegt
      • Sie schaut auf ihre Einkaufsliste, wie viel sie auf dem Konto hat
    • Benutzer entscheiden in 20 Sekunden ob sie eine Applikation behalten. Wenn sie 15 davon zum Starten benötigt...
      • Nur Spiele die man eh länger (10-30 Minuten) spielt dürfen länger brauchen (manche Utilities auch)
    • Immer mit einer Idee anfangen:
      • "Vielleicht inneneinrichtung machen?" -> Was könnte man machen? Viel.
      • "Vielleicht FoneLink auf das iPhone bringen?" -> Macht schweine viel....
      • Was ist die Lösung die man anbietet?
    • Define your solution:
      • Application Definition statement: Worum geht's wirklich? Was und für Wen ("iPhoto ist ein Programm zum sortieren, betrachten und teilen von Photos für Home-User und Amateure.")
      • Das ist das Sieb mit dem man Features aussiebt
    • Refine Features
      • Was ist das wenigste mit dem man durchkommt?
        • Wegschmeißen! Selber belohnen wenn man etwas rauslässt! :)
        • Sieben mit dem "Application Definition Statement"
      • Was ist Neu, Am häufigsten Benutzt, Von den meisten usern (80%), Passt für unterwegs Benutzung
      • Was passiert wenn man sich ver"klickt"?
      • Was wenn die Beleuchtung schlecht ist?
      • Weniger Information zu jedem Zeitpunkt anzeigen, dafür "drill down"
    • Welches Mentale Modell haben die Benutzer? Wie sieht er die Applikation?
      • Identify: Objects, Tasks, Roles, Relationships
  • Realize
    • Welche Art Programm baut man? (Welcher Typ?)
    • Produktivität: Lang benutzung (Mail), Wenig Graphik, Viele daten (Drilldown)
    • Utility: Ein Blick auf etwas, dann fertig
    • Immersive: Games, eigene Oberfläche, viel Graphik
    • Das kann man plotten: Von oben (Serious) nach unten (Fun), von links (Entertainment) nach rechts (Tool)
      • Oben Rechts (Serious Tool) Mail: Viel Text, Hierarchien, wenig Graphik
      • Unten Rechts: (Fun Tool) Social, Twitterific: Graphisch, wenig Text, Flache Hierarchien
      • Unten Links: (Fun Entertainment) Games: Graphisch, alles eigenes Interface
      • Oben Links: (Serious Entertainment) News: Text, wenig Graphik, Hierarchien (drill down)
      • Mitte: Utilities (Rest?) Wetter, Aktienkurse, Uhrzeit / Wecker
    • Objekthierarchie in der UI wiederspiegeln (Das hat mich überrascht, da man das auf dem Desktop ja eigentlich eher nicht machen will (Weil das Mentale Modell der user, nach dem man das Interface baut, nicht unbedingt der beste Implementierungsweg ist)
    • Mit Papier Iterieren (Welcher Screen kommt wo und wann?) immer wieder...
  • Finalize
    • Verbessern mit Photos und Bildern
    • Animation für Begeisterung und Feedback!
    • Refine, Optimize, Enhance

Zusammengefasst:

  • "Application Definition Statement" erstellen
  • Iterieren "early and often" (Auf Papier?)
  • Bis zum Release wiederholen - dann wieder von vorn. :)

UIKit Development

  • View Controllers stehen immer im Zentrum: "The C in MVC" :)
    • Einer für jeden Bildschirm / Screen in der App
    • Zwei Sorten: Custom Subclasses (Typischerweise 1 Screen), Apples Subklassen (machen mehrere Screens!)
    • "view" property zum ablegen des UIViews
    • wichtige delegate methoden: loadView: viewDidLoad: viewWillAppear: viewDidAppear:
    • initWithNibName:bundle: -> Designated initializer
    • Releasen wenn man fertig ist mit anzeigen -> Speicher sparen
    • Navigation controller: "Drill Down" interfaces
      • Managt andere ViewController!
      • wichtige Delegate Methoden: pushViewController:animated: popViewController:animated:
      • Wechselt Controller, Show/Hide NavigationController (für die Rückwärtsnavigation und wenige Aktionen)
    • UITabBarController: Verschiedene Ansichten auf die gleichen Daten (iTunes)
      • Managt NSViewControllers
      • More und Konfiguration (fast wie NSToolbar!)
      • Icons schwarz-weiß Outlines mit Alpha!
    • Toolbars: Tools und Aktionen (nur ein Icon)
      • Kein UIViewController!
      • OK: Modales-Sheet als Aktion bringen (Slide up from the bottom!)
      • Slide up meint: Etwas worauf man reagieren muss (Slide across meint navigating)
      • Nie im Tab-Switcher aktionen auslösen!
      • Bookmarks: Sheet dass den ganzen Bildschirm abdeckt
    • UITableViewController: Tabellen...
      • Plain (Adressbuch), Grouped (Prefs)
      • Header, Footer, Sektionen (wieder mit Header & Footer)
      • Jede menge delegate calls um es zu befüllen
      • UITableCells:
        • Kann: Bild, Text, Disclosure / Accessory (evtl. auch checkbox?)
        • Kann einfach Subviews hinzufügen (Yay, nie mehr SubviewTableViewController)
          • Speicher sparen: (Speziell beim scrollen wichtig, damit es flüssig ist) "Cellen" mit gleicher Klasse / Struktur sollten gleiche ID haben, dann kann man mit [tableView dequeReusableCellWithIdentifier:someID] die die oben rausgescrollt sind wieder verwenden statt jedesmal eine Neue zu machen
    • View Controller Tips
      • Immer festlegen ob man das View drehen kann oder nicht (Telefon verkehrt herum macht keinen Sinn - Spiele könnten aber auch in beiden Landscapes prima funktionieren)
      • Bildschirmgröße kann unterschiedlich sein: Beim Telefonieren ist die Statusbar doppelt so hoch!
      • Memory
        • Jeder UIViewController kriegt Memory-Warnings
        • applicationDidFinishLaunching -> leicht halten (für schnellen Startup)
        • Jedes UIKit View ist / hat einen core-animation Layer -> Macht spaß
        • Während der Animation (asynchron) die Applikation blockieren. Wenn der User irgendwo klickt und einen view-wechsel auslöst, der die Animation sinnlos macht...
  • Text Display:
    • UILabel, UIWebView (html, pdf, word)
    • NSString (UIStringDrawing)
    • UITextField (so wenig wie möglich, immer defaults anbieten!)
    • Keyboard Code: (UITextInputTraits) oder IB
      • shown in becomesFirstResponder hidden in resignFirstResponder
      • Cancel bedenken!
  • UITouch (ein Finger!)
    • multiTouch muss man per view einschalten!
    • Gesten muss man selber erkennen
    • touchesBegan:withEvent: touchesMoved:withEvent: touchesended:withEvent:
  • Accelerometer: Reichtung
    • deviceOrientationChanged: delegate
    • Oder direkt -[UIAccelerometer sharedAccelerometer]
      • möglichst wenig (baterie) grob: 10/sec, spiel: 30/sec
      • filtern! low pass (konstante bewegungen)-> Bubble-Level Sample, high-pass für plötzliche bewegungen
      • Kriegt keine konstante Bewegung oder Richtung mit
  • MediaPlayer: Full screen movies
  • Wichtig man kann zu jedem Zeitpunkt unterbrochen werden. Telefon, SMS, Termin (Telefonieren ist aber das wichtigste!)
    • Dann: Adio anhalten, Animation weg, Pausen-Funktion
    • Bei einem Telefonanruf: Erst wird eine Pause ausgelöst, und eine Dialogbox die dem User erlaubt das Telefonat anzunehmen oder abzuweisen, Wenn er annimmt, wird die Applikation terminiert, sonst "resumed"
  • CoreLocation
    • Filter setzen damit weniger callbacks notwendig sind: distanceFilter = xxx; desiredAccuracy = kConstant;
    • setzt man die filter "niedrig" genug wird möglicherweise GPS gar nicht angeworfen -> weniger Strom, schneller
    • Authorization Dialog: durch startUpdatingLocation -> lehnt der User ab muss man das behandeln (Muss man das jedes mal authorisieren?)

Optimization with Instruments

  • Wenig über Instruments und Shark. Mehr allgemeines Zeug
  • Man muss sich klarmachen was man wo an informationen kriegen kann:
    • Simulator: Mac: 2 ghz, 2 gig ram, 500 gb platte, 2mb l2 cache, ethernet, wifi
    • iPhone: 400mhz, 128 mb ram, 8-32 gb flash, kein cache, wifi, 3g, edge
  • Was messen: Speicher, Malen und Scrollen, Startzeit, Dateizugriff, Stromverbrauch
  • VM gibt's, aber kein swap, read only pages (memmap) werden aber geschossen und neu geladen
  • Keine Garbage Collector (man könnte sich aber mal an dem Boehm versuchen :)

Tips:

  • Static Memory minimieren
    • Code Size
    • Compiler flags (schon standardmäßig): -mthumb -> benutzt nur ein 16 Bit Subset und macht kleineren -> Floating point Code wird aber wesentlich größer -> Abwägen
    • "Dead Code Stripping" -> hilft aber nur bei C/C++ Code
    • Möglichst abschalten was man nicht braucht (C++ RTTI, Exceptions)
    • PNGs statt BMP/TIFF
    • Plists als binary Variante (macht Xcode automatisch beim Resourcen Kopieren)
  • Dynamic Memory
    • NSAutoreleasePools eher vermeiden sonst so nutzen wie mans machen soll -> computation intensive schleife -> alle 100/1000 mal einen neuen nehmen
    • "nonatomic" properties sind bis zu 10 mal schneller
    • leaks vermeiden....
  • Memory warnings
    • Unbedingt reagieren -> sonst wird die Applikation abgeschossen
    • Werden u.a. via den UIViewControllern geliefert
    • Dem Benutzer sagen dass die App gleich crashen könnte ist KEINE Lösung
  • Custom Drawing:
    • Views undurchsichtig (opaque) machen -> schneller
    • optimiert Zeichnen: -setNeedsDisplayInRect:, dann nur das in -drawRect: malen
    • Cachen was sich nicht verändert
    • Möglichst views nicht beim Scrollen allokieren -> langsam
      • "reusable cells" machen mehr sinn (siehe dequeue...)
    • Cell layer hierarchies zusammenfallen lassen? (Unklar was das genau sein soll
    • "Design for fast launch, short use"
    • "Optimize startup, Optimize quit"
    • Rest per lazy initializing
  • Große Datensets:
    • -[NSData initWithContentsOfMappedFile:]
    • SQLite für random access in großen Datensets
  • So wenig wie möglich schreiben
  • Sich schnell / langsam ändernde Daten trennen
  • Möglichst wenig Batterie verbrauchen
  • Möglichst wenig Netzwerktraffic
    • wenn doch: Viel auf einmal, wenig "chatty protokolls"
  • Location:
    • Holen, dann callbacks ausschalten
    • Genauigkeit nur so weit einschränken wie man es tatsächlich braucht

Piratenpartei Berlin Blog

written by Martin Häcker on

Noch zwar unter einer obskuren URL aber das ändert sich auch bald hat sich geändert.

Yay, wir haben einen Blog eingerichtet.

:)

Die Wahl in Amerika

written by Martin Häcker on

Faszinierend finde ich ja schöne verfahren um die Ergebnisse der Wahl vorherzusagen.

Toll finde ich in diesem Fall Crowdsourcing also die Idee, das lokale Wissen von ganz vielen Menschen über ihre Umgebung auf eine Art und Weise zusammen zu führen die daraus weit mehr macht als die Summe der einzelnen ist.

Eine Sache sind z.B. [Decision Markets] also eine Börse wo die leute Geld auf verschiedene Ergebnisse setzen können. Wie z.B. bei Intrade. Die haben zum Beispiel einen Markt für die Wahl heute Abend: Intrade - Realtime Election Tracking. Spannend vor allem die Übersicht über die letzten drei Monate.

Ein CCC'ler sagte dazu nur: "Decision Markets sind so genau, dass man damit sogar Wahlcomputer-Manipulationen nachweisen kann." Und dann: "Ich habe 100$ auf McCain gesetzt. Wenn er gewinnt krieg ich 950$." Die Antwort: "Auch ein Trostplfaster."

Spannend nicht?

Hier schon mal die Ergebnisse.

Delegation sucks

written by Martin Häcker on

Well, it doesn't really. But if way overused it becomes a pain in the a**.

This is not so much a problem in on itself, but the code sprouts dependencies that nobody is able to follow from just reading a class but which become crucial to the operation of the application.

Well, out of frustration I started thinking about the saying that Design-Patterns are just for languages that are not powerful enough to implement something in the language.

So lets see, what can we do to make this simpler:

if ([someObject respondsToSelector:@selector(someDelegateMethod:)]) {
    [someObject someDelegateMethod:self];
}

The key here is to only call the messagte -someDelegateMethod: if it is actually supported on the target. A perfect application [wiki:2008/10/26/20.59 of my invocation] [wiki:2008/10/25/01.21 catching code].

[[NMDelegateCaller callerForDelegate:object] someDelegateMethod:self];

In real life of course you would hide the delegator by just wrapping your delegate in the -setDelegate: method.

Interestingly implementing this proved rather more tricky than I anticipated. This is because of the way the objc-runtime creates NSInvocations out of c-method calls. The trick is, that really at runtime nothing is known about how arguments have to be scraped out of the stack because in C you have no clue what arguments actually are on the stack.

So objc takes a detour and stores this information alongside each method in the object that the method belongs to. This however has the unfortunate side effect that it should make just the delegator I wanted to build impossible to build. That is, because the runtime cannot build an NSInvocation out of a method call that the destination does not support - simply because it doesn't know what arguments are on the stack and what to return.

This is where my little evil hack comes in: I defined a method on NSObject that represents an identity for this situation - that is, it returns nothing and takes no argument - therefore the runtime won't crash anything by using it's description to build an NSInvocation. This is my marker.

And with this the problem becomes solvable - in -methodSignatureForSelector: I ask the target for a signature if it has one, and return my marker signature and let the runtime build an NSInvocation out of whatever method call was made (what exactly it was doesn't interest me, only that it's not implemented on the delegate). Then in -forwardInvocation: I can test if the signature is that marker and just discard the method if it is.

Voilá.

So it is proven - objc is powerful enough to implement this design pattern in itself - no need for all those if statements - and I learned a lot about the internals of NSInvocations.

Still I'm not sure if I really want to use that code. Yes it's shorter, but it's also a lot more complicated and it makes something very convenient which in essence I don't really want to be so convenient, because if overused it becomes a maintenance nightmare.

Also it lacks the simple elegance of just stating exactly what you want to achieve and returning good default values (my solution can just return NULL/NO/0 if the method is not implemented).

Damn. Alles für die Katz.

Still very interseting though. Maybe I'l find a different application that suits me more.

  • [source:open-source/NMInvocationBuilder/trunk Here's the code]

Syntax matters

written by Martin Häcker on

[wiki:2008/10/25/01.21 Gerade habe ich doch ein Stück Code hochgeladen] mit dem man jeden beliebigen Methodenaufruf in eine Invocation umwandeln kann.

Nun, das hat mir nicht gereicht. Jetzt hab ich mich noch mal hingesetzt und mich an einer anderen Syntax versucht:

// anstatt
id invocation = NMCatchInvocation(@"fnord", stringByAppendingString:@"42");

// jetzt
id invocation = [NMRecordingInvocation invocation];
[invocation recordWithTarget:@"fnord"] stringByAppendingString:@"42"];

// oder
id invocation = [NMRecordingInvocation invocationWithTarget:@"fnord"];
[invocation record] stringByAppendingString:@"42"];

Und ich finde das ist von der Syntax her deutlich eleganter als das Makro.

Allerdings:

  • Es ist etwa der doppelte Aufwand dass zu implementieren
  • Das Makro erzeugt viel schnelleren Code (viel weniger allokationen)

Was soll ich davon jetzt halten? Small is beautifull? Keep it simple stupid? Oder ist doch wichtiger dass der zweite Versuch eher dem Objc-Spirit entspricht?

Mir ist das auch nach einem Tag darüber nachdenken erheblich unklar.

  • [source:open-source/NMInvocationBuilder/trunk Hier gehts zum Code]

Grundeinkommen

written by Martin Häcker on

Spannend wars heute auf dem Kongress.

Vormittags der Workshop über Simulationsmodelle über die Auswirkungen der Einführung von Grundeinkommen auf ein Modell der österreichischen Volkswirtschaft (in dem sich zeigte dass Gewinnsteuerfinanziertes Grundeinkommen das verwendete Modell stärker destabilisierte als ein durch negative Einkommenssteur finanziertes.

Well, dafür das der verantwortliche für das Modell nur einen Tag lang simuliert hat...

Danach ging es noch ein bisschen mit zellulären automaten weiter um damit zu simulieren wie sich das Wissen um Grundeinkommen in der Bevölkerung ausbreiten konnte.

Beides nicht großartig, aber doch ein interessanter Einblick darin dass auch in der Simulation eben nur mit Wasser gekocht wird. Will sagen: Das hätte ich auch gekonnt.

Danach gabs dann einen Argumentationsworkshop gegen Stammtischparolen und Killerargumente - das war mal was praktisches und für mich (trotz einer was Argumente angeht eher mageren Ausbeute) damit das Highlight des Tages.

Schlussendich noch eine (gefühlt endlose) Podiumsdiskussion. Bei der ich wie auf Kohlen saß - mir ist nach wie vor noch nicht klar wieso ich das so extrem nervig fand. Naja.

Immerhin kam mir dabei noch eine interessante Idee: Viel beschworen ist ja die Angst vor der Arbeitsunwütigkeit der Bevölkerung wenn es ein Grundeinkommen gibt. Dass die dann nicht mehr Arbeiten würden und es sich nur noch gut gehen lassen werden.

Tja, das kann man doch einfach Testen. Alle Gemeinden < $GRENZWERT dürfen sich für eine Lotterie anmelden. Die Leute die in der Gemeinde leben die Gewinnt (und nur die die zu dem Zeitpunkt dort leben) kriegen dann von da ab bis an ihr Lebensende ein garantiertes und bedingungsloses Grundeinkommen.

Voila - schon weiß man bald viel mehr darüber wie sich Menschen mit Grundeinkommen verhalten. Und dann kann man bald die Angst dass die dann ja alle nicht mehr Arbeiten würden fundiert wiederlegen. (Ok, kann man IMO jetzt auch schon, aber es wäre halt doch etwas anderes)

Bonus wäre natürlich wenn man gleich mehrere solcher Versuche macht um verschiedene Rahmenbedingungen zu testen.

Billiger als ein Bankencrash wäre es allemal - und viel Produktiver.

NSInvocations zusammenbauen...

written by Martin Häcker on

...ist deutlich schmerzhaft.

Man muss eine Menge Aufwand treiben um aus einem objc-call etwas zu machen dass man schön hin und her passen kann.

Zum Beispiel:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    id aString = @"fnord";

    id signature = [aString methodSignatureForSelector:@selector(stringByAppendingString:)];
    id invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setTarget:aString];
    [invocation setSelector:@selector(stringByAppendingString:)];
    id appender = @"23";
    [invocation setArgument:&appender atIndex:2];

    [invocation invoke];

    id returnValue = nil;
    [invocation getReturnValue:&returnValue];

    NSLog(@"Got: %@", returnValue);

    [pool drain];
    return 0;
}

Das nervt sobald man es öfters als einmal machen muss.

Darum hab ich mir nach langem nachdenken mal etwas zusammengebaut das das erleichtert. Es ist nicht perfekt und ich hab auch eine Menge Ideen wie man es noch schöner machen kann, aber es funktioniert. :)

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    id invocation = NMCatchInvocation(@"fnord", stringByAppendingString:@"23");

    [invocation invoke];

    id returnValue = nil;
    [invocation getReturnValue:&returnValue];

    NSLog(@"Got: %@", returnValue);

    [pool drain];
    return 0;
}

Und das sieht schon bedeutend besser aus.

  • [source:open-source/NMInvocationBuilder/trunk Hier gehts zum Code]