<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>heikomaass</title>
	<atom:link href="http://www.heikomaass.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.heikomaass.de</link>
	<description>Keep on learning...</description>
	<lastBuildDate>Sun, 22 Apr 2012 21:53:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Good Webservice Design</title>
		<link>http://www.heikomaass.de/2012/04/06/good-webservice-design/</link>
		<comments>http://www.heikomaass.de/2012/04/06/good-webservice-design/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 16:14:48 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[Webapplikation Workout]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=499</guid>
		<description><![CDATA[Was zeichnet eigentlich einen guten Webservice aus ? Hier eine Liste von Anforderungen, die ein guter Webservice erfüllen muss. 1. Versioniert Webservices ändern sich. Im Idealfall kommen nur neue, optionale Attribute hinzu, ohne dass ältere Clients kaputt gehen. Bei umfangreicheren &#8230; <a href="http://www.heikomaass.de/2012/04/06/good-webservice-design/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Was zeichnet eigentlich einen guten Webservice aus ? Hier eine Liste von Anforderungen, die ein guter Webservice erfüllen muss.</p>
<p><strong>1. Versioniert</strong><br />
Webservices ändern sich. Im Idealfall kommen nur neue, optionale Attribute hinzu, ohne dass ältere Clients kaputt gehen. Bei umfangreicheren Umstrukturierungen ist dies aber nicht der Fall: Die neue Version ist nicht mehr rückwertskompatibel. Hier muss sowohl die alte und die neue Version des Webservice eine Zeit lang parallel betrieben werden. Von daher muss die Version in die URL des Webservice mit aufgenommen werden (z.B. <a href="http://api.stackexchange.com/2.0/tags?order=desc&#038;sort=popular&#038;site=stackoverflow">http://api.stackexchange.com/<strong>2.0</strong>/tags?order=desc&#038;sort=popular&#038;site=stackoverflow</a>).</p>
<p><strong>2. Zustandslos</strong><br />
Ein Webservice darf keine Session-Ids oder gar Cookies einsetzen. Lesende Requests sollten unabhängig von einander ausgeführt werden können; eine bestimmte Reihenfolge darf nicht vorgegeben sein.</p>
<p><strong>3. Verständlich auch ohne Dokumentation</strong><br />
Methodennamen und Parameter sollten nicht kryptisch sein. Beispiel: Die Bedeutung von <code>totalHits</code> ist verständlicher als die von <code>th</code>. Zwar werden bei der kürzeren Variante ein paar Bytes eingespart, aber auf Kosten der Verständlichkeit. Wie Bytes besser eingespart werden, zeigt der nächste Punkt.</p>
<p><strong>4. Kompakt</strong><br />
Der Webserver sollte die GZIP-Komprimierung anbieten. Des weiteren sollte der Webservice auch JSON zurückgeben, um das Parsen für die Clients zu erleichtern und die Datenmenge zusätzlich zu reduzieren.</p>
<p><strong>5. Im Browser testbar</strong><br />
Jeder Webservice muss eine Testseite zur Verfügung stellen, auf der alle Requests und Parameter ausprobiert werden können. Beispiele dafür:</p>
<ul>
<li><a href="https://api.stackexchange.com/docs" title="https://api.stackexchange.com/docs">https://api.stackexchange.com/docs</a></li>
<li><a href ="http://www.flickr.com/services/api/explore/flickr.galleries.getPhotos">http://www.flickr.com/services/api/explore/flickr.galleries.getPhotos</a></li>
</ul>
<p>Testseiten erleichtern das Erlernen des Webservices und ermöglichen den schnellen Test unabhängig von irgendwelchen Tools. Gute Testseiten können sogar eine separate Dokumentation ersetzen.</p>
<p><strong>6. Auskunftsfreudig bei Fehlern</strong><br />
Es ist ziemlich frustrierend, wenn der Webservice bei syntaktisch falschen oder fehlenden Parametern einfach nur eine Standardfehlermeldung zurückgibt. Wichtig ist, dass der Webservice mitteilt, was genau schief gelaufen ist. Beispiel: </p>
<pre>
{
  "error" : {
    "name" : "missing_parameter",
    "description" : "parameter 'lang' is missing"
  }
}
</pre>
<p>Des Weiteren muss der Server bei einem Fehlerfall auch den HTTP-Code korrekt setzen. Bei clientseitigen Fehlern sollte der Server einen <code>HTTP 400 (Bad Request)</code> schicken, bei serverseitigen Fehlern dagegen einen <code>HTTP 500 (Internal Server Error)</code>. Dies erleichtert das Cachingverhalten und die Fehlerbehandlung auf Seiten des Clients.</p>
<p><strong>7. Konsistent</strong><br />
Parameternamen sollten über alle Methoden hinweg identisch benannt werden. Ansonsten muss der Client diese Inkonsistenzen abfangen, was die Client-Implementierung wieder aufwändiger macht.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/04/06/good-webservice-design/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Pimp up your VIM &#8211; NERDTree</title>
		<link>http://www.heikomaass.de/2012/03/31/pimp-up-your-vim-nerdtree/</link>
		<comments>http://www.heikomaass.de/2012/03/31/pimp-up-your-vim-nerdtree/#comments</comments>
		<pubDate>Sat, 31 Mar 2012 22:25:04 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[IDE]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=457</guid>
		<description><![CDATA[Heute bin ich auf die VIM-Erweiterung &#8220;NERDTree&#8221; gestossen. Diese Erweiterung platziert einen navigierbaren Verzeichnisbaum an die linke Seite des Editors. Zwar hat VIM einen eigenen Editor-Browser (Aufrufbar mit :E), aber mit NERDTree arbeitet es sich deutlich effizienter. Die wichtigsten Shortcuts &#8230; <a href="http://www.heikomaass.de/2012/03/31/pimp-up-your-vim-nerdtree/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute bin ich auf die VIM-Erweiterung &#8220;<a href="https://github.com/scrooloose/nerdtree" title="NERDTree">NERDTree</a>&#8221; gestossen. Diese Erweiterung platziert einen navigierbaren Verzeichnisbaum an die linke Seite des Editors. Zwar hat VIM einen eigenen Editor-Browser (Aufrufbar mit :E), aber mit NERDTree arbeitet es sich deutlich effizienter.</p>
<p><img src="/wp-content/uploads/2012/NERDTree.png" title="Screenshot eines Mac-Terminals mit geöffneten VIM und der NERDTree-Erweiterung" class="alignleft" /></p>
<h3>Die wichtigsten Shortcuts</h3>
<ul>
<li><code>j</code> &#8211; Runter</li>
<li><code>k</code> &#8211; Hoch</li>
<li><code>SHIFT-C</code> &#8211; Wechsel in das aktuell selektierte Verzeichnis</li>
<li><code>u</code> &#8211; Wechsel in das Parent-Verzeichnis.</li>
<li><code>m</code> &#8211; Aktionsmenü (add, move, delete, copy)</li>
<li><code>ENTER</code> &#8211; Editiern der ausgewählten Datei</li>
</ul>
<h3>Installation</h3>
<p>Die Installation erfolgt sehr einfach über <a href="https://github.com/tpope/vim-pathogen" title="Pathogen">Pathogen</a>-Bundle. Damit NERDTree automatisch gestartet wird, muss folgendes Autocommand in die <code>~/.vimrc</code> eingetragen werden: </p>
<div class="codeblock">
<pre>
autocmd vimenter * NERDTree
</pre>
</div>
<p>Etwas unschön ist, dass beim Öffnen von vim nun immer das NERDTree-Window fokussiert ist. Um in das andere Window zu springen, muss man die Tastenkombination <code>CTRL-W w</code> drücken . </p>
<p>Dies lässt sich jedoch durch einen Eintrag in die <code>~/.vimrc</code> automatisieren:</p>
<div class="codeblock">
<pre>
autocmd vimenter * wincmd w
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/03/31/pimp-up-your-vim-nerdtree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spass mit Websphere 6 &#8211; Teil 1</title>
		<link>http://www.heikomaass.de/2012/03/29/spass-mit-websphere-6-teil-1/</link>
		<comments>http://www.heikomaass.de/2012/03/29/spass-mit-websphere-6-teil-1/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 20:43:57 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[Webapplikation Workout]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=447</guid>
		<description><![CDATA[Wie ich diese Woche feststellen durfte, implementiert der IBM Websphere 6.x (und sogar der Websphere 7.x) die Servlet Specification nicht richtig. Konkret geht es um das Verhalten von getServletPath() und getPathInfo() des HttpServletRequests. Wie es sein muss: Angenommen, wir haben &#8230; <a href="http://www.heikomaass.de/2012/03/29/spass-mit-websphere-6-teil-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wie ich diese Woche feststellen durfte, implementiert der IBM Websphere 6.x (und sogar der Websphere 7.x) die Servlet Specification nicht richtig. Konkret geht es um das Verhalten von <code>getServletPath()</code> und <code>getPathInfo()</code> des <code>HttpServletRequest</code>s.</p>
<h3>Wie es sein muss:</h3>
<p>Angenommen, wir haben eine Webapp unter dem Context <code>mystore</code> und mappen genau ein Servlet auf den Defaultpath &#8220;/&#8221;. Wenn wir folgende URL aufrufen: <code>/mystore/search/de</code>, dann sehen wir im Apache Tomcat folgendes:</p>
<p><code>getServletPath(): "/search/de"<br />
getPathInfo(): <del datetime="2012-04-01T19:41:41+00:00">null</del>""</code><br />
<em>Editiert am 1.4.2012: Der Tomcat liefert einen leereren String, anstelle von <code>null</code> zurück. </em></p>
<p>Dieses Verhalten wird in der Servlet Api 2.4 unter dem Kapitel &#8220;Specification of Mappings&#8221; festgelegt:</p>
<blockquote><p>
A string containing only the ’/’ character indicates the &#8220;default&#8221; servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
</p></blockquote>
<h3>Wie es der Websphere macht:</h3>
<p>Der Websphere behandelt das Default-Mapping genauso wie ein Directory-Mapping also &#8220;/*&#8221;. Somit gibt er folgendes zurück:</p>
<p><code>getServletPath(): ""<br />
getPathInfo(): "/search/de"</code></p>
<p>Das ist natürlich unglücklich, da man im Code nun eine Fallunterscheidung machen muss.</p>
<h3>Spring hilft:</h3>
<p><del datetime="2012-04-01T19:41:41+00:00">Die Methode <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/util/UrlPathHelper.html#getPathWithinServletMapping%28javax.servlet.http.HttpServletRequest%29">getPathWithinServletMapping</a> aus der UrlPathHelper-Klasse des Spring Frameworks schafft hier Abhilfe. Wenn getServletPath() <code>null</code> ist, liefert die Methode stattdessen die Antwort von <code>getPathInfo()</code> zurück. <b>Wichtig:</b> Dies funktioniert aber erst seit dem Spring Release 3.0.3.</del><br />
<em>Editiert am 1.4.2012: getPathWithinServletMapping() gibt natürlich nicht den ServletPath zurück, sondern nur die Pfadangabe hinter dem ServletPath. Von daher ist dies nicht die korrekte Lösung. Nachfolgend stelle ich stattdessen die Methode <code>getPathWithinApplication</code> vor, die mir in meinem Anwendungsfall die Fallunterscheidung zwischen Websphere und Tomcat erspart hat:</em></p>
<p>Die Methode <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/util/UrlPathHelper.html#getPathWithinApplication%28javax.servlet.http.HttpServletRequest%29">getPathWithinApplication</a> aus der UrlPathHelper-Klasse des Spring Frameworks liefert den restlichten Pfad nach dem Context, unabhängig ob er vom ServletPath oder PathInfo kommt.</p>
<h3>Weitere Lektüre:</h3>
<p><a href="http://www-01.ibm.com/support/docview.wss?uid=swg1PK39337">http://www-01.ibm.com/support/docview.wss?uid=swg1PK39337</a><br />
<a href="https://issues.apache.org/jira/browse/TAPESTRY-1713">https://issues.apache.org/jira/browse/TAPESTRY-1713</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/03/29/spass-mit-websphere-6-teil-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meine Terminal-Konfiguration</title>
		<link>http://www.heikomaass.de/2012/03/07/meine-terminal-konfiguration/</link>
		<comments>http://www.heikomaass.de/2012/03/07/meine-terminal-konfiguration/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 19:00:04 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[IDE]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=417</guid>
		<description><![CDATA[Hier eine kleine Liste von praktischen Konfigurationseinstellungen für die Arbeit mit dem Terminal unter Mac OS X. 1. &#8220;IR_Black&#8221;-Theme Das wohl schönste Theme für das Mac Terminal ist &#8220;IR_Black&#8221;, zu finden unter http://blog.toddwerth.com/entries/13. Das einzige, was ich an diesem Theme &#8230; <a href="http://www.heikomaass.de/2012/03/07/meine-terminal-konfiguration/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hier eine kleine Liste von praktischen Konfigurationseinstellungen für die Arbeit mit dem Terminal unter Mac OS X.</p>
<h3>1. &#8220;IR_Black&#8221;-Theme</h3>
<p>Das wohl schönste Theme für das Mac Terminal ist &#8220;IR_Black&#8221;, zu finden unter <a href="http://blog.toddwerth.com/entries/13">http://blog.toddwerth.com/entries/13</a>. Das einzige, was ich an diesem Theme noch nachträglich ändern musste, war der Cursor-Typ: Ein Blockcursor muss einfach sein.</p>
<h3>2. Alias für ls</h3>
<p>Folgende Optionen möchte ich bei jedem &#8220;ls&#8221; haben:</p>
<ul>
<li><b>-G</b> Ausgabe in Farbe</li>
<li><b>-F</b> Fügt Suffixes hinter jedes ausgegebene Objekt. Bsp. ein Slash (/) für ein Verzeichnis </li>
<li><b>-h</b> Gibt Dateigrössen in einer lesbareren Form zurück</li>
</ul>
<p>Damit diese Optionen immer verwendet werden, setze ich ein alias auf <code>ls</code> in <code>~/.bash_profile.</code></p>
<div class="codeblock">
<pre>
alias ls='ls -GFh'
</pre>
</div>
<h3>3. Syntax highlighting in VIM</h3>
<p>Nächster Schritt: Ich möchte in VIM immer ein Syntax-Highlighting verwenden. Dazu lege ich die Datei <code>~/.vimrc</code> mit folgenden Inhalt an:</p>
<div class="codeblock">
<pre>
syntax on
</pre>
</div>
<h3>4. Bash completion für GIT</h3>
<p>(Danke <a href="http://www.printhelloworld.de/" title="Johannes Blog">Johannes</a> für diesen Tipp). Es gibt für Git ein &#8220;completion support&#8221;-Skript für Bash. So kann man kontextabhängig die zur Verfügung stehenden Git-Befehle mit Tab anzeigen lassen. </p>
<p>Erst lade ich das Bashskript von Github runter:</p>
<div class="codeblock" style=" overflow:scroll;">
<pre>
cd ~
curl -o .git-completion.bash https://raw.github.com/git/git/master/contrib/completion/git-completion.bash
</pre>
</div>
<p>Anschliessend braucht es noch folgenden zusätzlichen Eintrag in die <code>~/.bash_profile</code>:</p>
<div class="codeblock">
<pre>
source .git-completion.bash
</pre>
</div>
<p>Fertig.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/03/07/meine-terminal-konfiguration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HMLauncherView</title>
		<link>http://www.heikomaass.de/2012/03/06/hmlauncherview/</link>
		<comments>http://www.heikomaass.de/2012/03/06/hmlauncherview/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 22:11:39 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=407</guid>
		<description><![CDATA[Letzte Woche habe ich meine iOS-Komponente &#8220;HMLauncherView&#8221; auf Github hochgeladen. Die Komponente bietet eine Alternative zu der TTLauncherView aus dem Three20-Framework. Das Besondere ist, dass auch mehrere &#8220;LauncherViews&#8221; interagieren können. So können Buttons von einer Liste zur anderen verschoben werden &#8230; <a href="http://www.heikomaass.de/2012/03/06/hmlauncherview/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Letzte Woche habe ich meine iOS-Komponente &#8220;HMLauncherView&#8221; auf Github hochgeladen. Die Komponente bietet eine Alternative zu der TTLauncherView aus dem Three20-Framework. Das Besondere ist, dass auch mehrere &#8220;LauncherViews&#8221; interagieren können. So können Buttons von einer Liste zur anderen verschoben werden (Siehe Video).</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/Mqv1usdM6fA" frameborder="0" allowfullscreen></iframe></p>
<p>Ausbaufähig ist noch die Dokumentation, aber das kommt auch noch.</p>
<p>Link zu Github: <a href="https://github.com/heikomaass/HMLauncherView">https://github.com/heikomaass/HMLauncherView</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/03/06/hmlauncherview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erzeuge keine UIViews in der init-Methode eines UIViewControllers</title>
		<link>http://www.heikomaass.de/2012/02/17/erzeuge-keine-uiviews-in-der-init-methode-eines-uiviewcontrollers/</link>
		<comments>http://www.heikomaass.de/2012/02/17/erzeuge-keine-uiviews-in-der-init-methode-eines-uiviewcontrollers/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 21:38:05 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=325</guid>
		<description><![CDATA[Vor einiger Zeit hatte ich bei einem Code-Review folgende init-Methode eines UIViewControllers gesehen: - (id) init { if (self = [super init]) { UIImage *image = [UIImage imageNamed:@"someimage.png"]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; self.logoImageView = imageView; [imageView release]; } &#8230; <a href="http://www.heikomaass.de/2012/02/17/erzeuge-keine-uiviews-in-der-init-methode-eines-uiviewcontrollers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Vor einiger Zeit hatte ich bei einem Code-Review folgende <code>init</code>-Methode eines <code>UIViewController</code>s gesehen:</p>
<div class="codeblock" style="overflow:scroll">
<pre>
- (id) init {
	if (self = [super init]) {
		UIImage *image = [UIImage imageNamed:@"someimage.png"];
		UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
		self.logoImageView = imageView;
		[imageView release];
	}
	return self;
}

- (void) dealloc {
   [logoImageView release];
   [super dealloc];
}
</pre>
</div>
<p>Was ist daran falsch ? Bevor ich die Frage beantworte, möchte ich den Lifecycle eines <code>UIViewController</code>-Objekts stark vereinfacht vorstellen:</p>
<h3>Lifecycle</h3>
<p>Der Lifecycle eines <code>UIViewController</code>s umfasst folgende Methodenaufrufe:</p>
<ol>
<li>init</li>
<li>loadView</li>
<li>viewDidLoad</li>
<li>(Optional) viewDidUnload</li>
<li>dealloc</li>
</ol>
<p>Die init-Methode (1.) wird nur 1x im Leben eines <code>UIViewController</code>-Objekts aufgerufen. Sobald das erste Mal auf das <code>view</code>-Property eines <code>UIViewController</code>s zugegriffen wird, ruft UIKit die <code>loadView</code>-Methode (2.) auf, um die View für den Controller zu erzeugen. Anschliessend ruft UIKit die Methode <code>viewDidLoad</code> (3.) auf. Bei Speichermangel (Memory Warning) reagiert der <code>UIViewController</code> und führt die Methode <code>viewDidUnload</code> (4.) aus, sofern die View nicht gerade sichtbar ist. Zitat: </p>
<blockquote><p>
When a low-memory condition occurs and the current view controller’s views are not needed, the system may opt to remove those views from memory.<br />
[...]  If your view controller stores references to the view or its subviews, you should use this method to release those references<br />
<a href="https://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidUnload">Dokumentation viewDidUnload</a>
</p></blockquote>
<p>Wenn die View des Controllers durch <code>viewDidUnload</code> abgeräumt wurde, dann muss sie natürlich beim nächsten Zugriff wieder erstellt werden. In diesem Fall wird <code>loadView</code> und <code>viewDidLoad</code> erneut aufgerufen. Dieser Zyklus kann sich beliebig häufig wiederholen.</p>
<h3>Keine UIViews in init erzeugen</h3>
<p>So. Zurück zur Anfangsfrage: Warum sollte man keine UIViews in der <code>init</code>-Methode anlegen ? Der Grund ist einfach: Sie können so bei Speichermangel nicht abgeräumt werden. Wenn man beispielsweise eine <code>UIImageView</code> im <code>init</code> erzeugen und in <code>viewDidUnload</code> releasen würde, dann würde sie nie wieder neu erzeugt werden, da <code>init</code> ja nur 1x aufgerufen wird. Das Resultat sind fehlende Views bei Speichermangel.</p>
<p>Kurzum: UIViews sollen nie im <code>init</code>, sondern immer nur im <code>loadView</code> oder in <code>viewDidLoad</code> angelegt werden. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/02/17/erzeuge-keine-uiviews-in-der-init-methode-eines-uiviewcontrollers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Das iOS-Framework &#8220;Three20&#8243; in der Retrospektive</title>
		<link>http://www.heikomaass.de/2012/02/14/das-ios-framework-three20-in-der-retrospektive/</link>
		<comments>http://www.heikomaass.de/2012/02/14/das-ios-framework-three20-in-der-retrospektive/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 21:58:33 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=292</guid>
		<description><![CDATA[Vor fast zwei Jahren stand ich vor dem Problem, eine Schnellstart-Buttonleiste in eine iPhone-App einzubauen. Die Buttons in der Leiste sollten analog zum iPhone-Homescreen mittels Drag&#038;Drop sortiert werden können. Bei der Recherche nach einer bereits fertigen Open Source-Komponente bin ich &#8230; <a href="http://www.heikomaass.de/2012/02/14/das-ios-framework-three20-in-der-retrospektive/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Vor fast zwei Jahren stand ich vor dem Problem, eine Schnellstart-Buttonleiste in eine iPhone-App einzubauen. Die Buttons in der Leiste sollten analog zum iPhone-Homescreen mittels Drag&#038;Drop sortiert werden können. </p>
<p>Bei der Recherche nach einer bereits fertigen Open Source-Komponente bin ich auf das<br />
<a href="http://three20.info/">Three20</a>-Framework gestossen, dass damals von vielen Projekten eingesetzt wurde. Auf der Webseite von Three20 wird der eigene Launcher als wichtiges Feature <a href="http://three20.info/showcase/launcher">angeteasert</a>. </p>
<p>Three20 wurde von <a href="http://joehewitt.com/">Joe Hewitt</a> ursprünglich für die Facebook-iPhone-App entwickelt. Joe kommt aus der &#8220;Webwelt&#8221; und hat vorher den äusserst nützlichen <a href="https://addons.mozilla.org/de/firefox/addon/firebug/">Firebug</a> ins Leben gerufen. Mit Three20 hat er versucht, Ideen aus der Webentwicklung in die iOS-Welt zu übertragen. Beispielsweise werden die UIViewController mit URLs versehen, die über einen eigenen Dispatcher (TTNavigator) aufgerufen werden. Zudem können UI-Elemente ähnlich wie CSS über einen Stylesheet (TTStyleSheet) angepasst werden. </p>
<p>Mir waren die (zugegeben interessanten) Ansätze jedoch viel zu invasiv.<br />
Der TTNavigator und die Stylesheets verstehen sich quasi als &#8220;Gegen&#8221;-Framework zum UIKit,<br />
und das kann auf Dauer nicht funktionieren. Ich hatte damals lediglich die TTLauncherView-Klasse in mein Projekt integriert.</p>
<p>Soweit so schön. Jetzt kommt jedoch der Haken der Story:</p>
<p>Bei jedem iOS-Update hatte ich Probleme mit Three20, da das Framework erst an Apple&#8217;s Änderungen angepasst werden musste. Auch beim Upgrade von XCode 3 auf XCode 4 kam es aufgrund des komplexen, intranparenten Buildsystems von Three20 zu Komplikationen. Joe Hewitt hatte mittlerweile <a href="http://allthingsd.com/20110506/key-developer-joe-hewitt-leaves-facebook/">Facebook verlassen</a>, und der neue <a href="https://github.com/jverkoey">Projektverantwortliche</a> musste dann einen Monat später leider folgendes Fazit über Three20 ziehen:</p>
<blockquote>
<ul>
<li>Poor documentation.</li>
<li>Spaghetti dependencies.</li>
<li>Suffering from a &#8220;kitchen sink&#8221; complex.</li>
<li>A complex build structure.</li>
<li>An enormous number of difficult-to-solve bugs.</li>
<li>Next-to-zero test coverage.</li>
</ul>
<p>Quelle: <a href="https://github.com/jverkoey/nimbus">https://github.com/jverkoey/nimbus</a> (Absatz &#8220;Nimbus Background&#8221;)
</p></blockquote>
<p>Aus diesen Gründen gibts nun das Nachfolger-Framework &#8220;Nimbus&#8221; (https://github.com/jverkoey/nimbus). Leider wird dies auf der Three20-Projektwebseite nicht erwähnt. Von daher die Warnung auf dieser Seite: <strong>Don&#8217;t use it!</strong></p>
<p>Vor knapp vier Monaten stand ich erneut vor dem &#8220;Problem&#8221;, eine Schnellstart-Buttonleiste in eine iOS-App zu integrieren. Diesmal habe ich es komplett selber programmiert.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/02/14/das-ios-framework-three20-in-der-retrospektive/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Und jetzt: Aus javablog.ch wird heikomaass.de</title>
		<link>http://www.heikomaass.de/2012/02/14/und-jetzt-aus-javablog-ch-wird-heikomaass-de/</link>
		<comments>http://www.heikomaass.de/2012/02/14/und-jetzt-aus-javablog-ch-wird-heikomaass-de/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 22:57:57 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.heikomaass.de/?p=280</guid>
		<description><![CDATA[So: Die RewriteRules sind konfiguriert und die Name-Server bei der SWITCH ausgetauscht. Google ist dank der Webmaster Tools ebenfalls über den Umzug informiert. Jetzt kann ja nichts mehr schiefgehen Wie im Kommentar meines vorherigen Blogeintrag angekündigt, wird aus dem eher &#8230; <a href="http://www.heikomaass.de/2012/02/14/und-jetzt-aus-javablog-ch-wird-heikomaass-de/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So: Die RewriteRules sind konfiguriert und die Name-Server bei der SWITCH ausgetauscht. Google ist dank der Webmaster Tools ebenfalls über den Umzug informiert. Jetzt kann ja nichts mehr schiefgehen <img src='http://www.heikomaass.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </p>
<p>Wie im Kommentar meines vorherigen Blogeintrag angekündigt, wird aus dem eher themenbezogenen JavaBlog nun ein persönliches Blog (Danke nochmals an Jürg für seine Anregung). Diese Entscheidung zieht natürlich einen Domain-Wechsel mit sich.</p>
<p>Alle alten URLs funktionieren weiterhin, sie werden über einen HTTP 301 auf die entsprechende Seite hier weitergeleitet.</p>
<p>(Im Übrigen danke noch an das Supportteam von All-Inkl, die sogar noch Sonntag Nacht sehr zügig antworten).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/02/14/und-jetzt-aus-javablog-ch-wird-heikomaass-de/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Und jetzt ?</title>
		<link>http://www.heikomaass.de/2012/02/11/und-jetzt/</link>
		<comments>http://www.heikomaass.de/2012/02/11/und-jetzt/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 17:27:30 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.javablog.ch/?p=267</guid>
		<description><![CDATA[Knapp ein Jahr habe ich auf diesem Blog nichts mehr geschrieben. Mit meiner zunehmenden Fokussierung auf das &#8220;Mobile&#8221;-Thema kann ich mich mit JavaBlog auch nicht mehr wirklich anfreunden, da ich in letzter Zeit viel in Objective-C programmiert habe. Natürlich spielt &#8230; <a href="http://www.heikomaass.de/2012/02/11/und-jetzt/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Knapp ein Jahr habe ich auf diesem Blog nichts mehr geschrieben. Mit meiner zunehmenden Fokussierung auf das &#8220;Mobile&#8221;-Thema kann ich mich mit <strong>Java</strong>Blog auch nicht mehr wirklich anfreunden, da ich in letzter Zeit viel in Objective-C programmiert habe. </p>
<p>Natürlich spielt Java für mich weiterhin eine große Rolle (Stichwort Android), aber es ist eben nur ein Ausschnitt aus meiner Tätigkeit.</p>
<p>Ob ich jetzt mein Blog umbenenne oder einfach ein Neues aufmache, weiss ich noch nicht. Aber das Bloggen möchte ich definitiv nicht aufgeben.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2012/02/11/und-jetzt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JDK7 Testfahrt &#8211; Teil 2</title>
		<link>http://www.heikomaass.de/2011/03/27/jdk7-testfahrt-teil-2/</link>
		<comments>http://www.heikomaass.de/2011/03/27/jdk7-testfahrt-teil-2/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 21:48:00 +0000</pubDate>
		<dc:creator>HeikoMaass</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.javablog.ch/?p=246</guid>
		<description><![CDATA[&#8220;Catching Multiple Exception Types&#8221; Ein praktisches Feature, um doppelte catch-Blöcke zu vermeiden. Es ist nun möglich mit einem Catch-Block mehrere Exception-Typen gleichzeitig zu fangen. Die Exception-Typen werden dabei mit dem ODER-Operator (&#124;) getrennt. Im Catch-Block kann die gefangene Exception unter &#8230; <a href="http://www.heikomaass.de/2011/03/27/jdk7-testfahrt-teil-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>&#8220;Catching Multiple Exception Types&#8221;</h3>
<p>Ein praktisches Feature, um doppelte catch-Blöcke zu vermeiden. Es ist nun möglich mit einem Catch-Block mehrere Exception-Typen gleichzeitig zu fangen. Die Exception-Typen werden dabei mit dem ODER-Operator (|) getrennt. Im Catch-Block kann die gefangene Exception unter gemeinsamen Supertyp angesprochen werden.   </p>
<div class="codeblock">
<pre>
   static class AException extends Exception {
        public void fooFromA() {}
    }
    static class BException extends AException {
        public void fooFromB() {}
    }
    static class CException extends AException {
        public void fooFromC() {}
    }

    public void x() {
        try {
            z();
        } catch (BException | CException e) {
            e.fooFromA();
            // e.fooFromB(); Compiler-Fehler
            // e.fooFromC(); Compiler-Fehler
        }
    }

    public void z() throws BException, CException {
        // heavy lifting
    }
</pre>
</div>
<h3>&#8220;Improved Checking for Rethrown Exceptions&#8221;</h3>
<p>Des Weiteren &#8220;merkt&#8221; sich der Compiler nun, welche Exception-Typen im try-Block geworfen können. So kann im Catch-Block ein Supertyp gefangen und weiter geworfen werden, auch wenn dieser Supertyp gar nicht in der throws-Deklaration vorkommt. </p>
<div class="codeblock">
<pre>
 public void y() throws BException, CException {
        try {
            z();
        } catch (Throwable e) {
            // e darf ohne Cast weiter geworfen werden, da
            // der Compiler sich "gemerkt hat", dass im
            // try-Block nur BException und CException
            // vorkommen können.
            throw e;
        }
    }
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.heikomaass.de/2011/03/27/jdk7-testfahrt-teil-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

