SlideShare ist ein Scribd-Unternehmen logo
1 von 81
Pitfalls bei der iOS-Entwicklung
       Dipl.-Inform. (FH) Sven Günther
       Agiler Senior Softwareentwickler
     sven.guenther@it-agile.de - @iNevs



             http://www.it-agile.de
About


   Softwareentwickler seit 1997
   erste Programmiersprache: C
   Objective-C seit 2007
   iOS Entwicklung seit 2009
   Berater und Coach für agile Softwareentwicklung


                            gegründet 2005
                            Sitz in Hamburg und München
                            32 Mitarbeiter
                            Beratung, Schulung, Coaching in agilen Methoden
                               Scrum, Kanban, xTreme Programming
                            Develop With You
                            Develop 4 You

    Sven Günther               http://www.it-agile.de                      2
Analyse der Crash-Reports

 Speicherprobleme
    Speicher ging aus
    kein Response auf Memory-Warnings
    System hat Programm abgeschossen




   Sven Günther                  http://www.it-agile.de   3
Analyse der Crash-Reports

 Speicherprobleme
    Speicher ging aus
    kein Response auf Memory-Warnings
    System hat Programm abgeschossen


 Crashes
    Threading-Probleme
    Zugriff auf freigegebenen Speicher




   Sven Günther                    http://www.it-agile.de   3
Speicherverwaltung




  Sven Günther       http://www.it-agile.de   4
Speicherverwaltung

 iPhone: 256MB RAM




   Sven Günther       http://www.it-agile.de   4
Speicherverwaltung

 iPhone: 256MB RAM
 Speicher ist begrenzt und daher kostbar




    Sven Günther               http://www.it-agile.de   4
Speicherverwaltung

 iPhone: 256MB RAM
 Speicher ist begrenzt und daher kostbar
 im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden




   Sven Günther                http://www.it-agile.de                      4
Speicherverwaltung

 iPhone: 256MB RAM
 Speicher ist begrenzt und daher kostbar
 im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden




   Sven Günther                http://www.it-agile.de                      4
Speicherverwaltung

 iPhone: 256MB RAM
 Speicher ist begrenzt und daher kostbar
 im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden

 Wie kann Speicher ausgehen?




   Sven Günther                 http://www.it-agile.de                     4
Speicherverwaltung

 iPhone: 256MB RAM
 Speicher ist begrenzt und daher kostbar
 im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden

 Wie kann Speicher ausgehen?
 Leaks
     Speicher auf den keine Referenz mehr besteht




   Sven Günther                     http://www.it-agile.de                 4
Speicherverwaltung

 iPhone: 256MB RAM
 Speicher ist begrenzt und daher kostbar
 im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden

 Wie kann Speicher ausgehen?
 Leaks
     Speicher auf den keine Referenz mehr besteht
 Verlassener Speicher
     Speicher der unnötig referenziert aber nicht mehr benutzt wird




   Sven Günther                      http://www.it-agile.de                4
Leaks



Was sind Leaks?

                                                                        Memory

MyClass *foo = [[MyClass alloc] init];                            foo

                                                                         0x0




   Sven Günther                          http://www.it-agile.de                  5
Leaks



Was sind Leaks?

                                                                        Memory

MyClass *foo = [[MyClass alloc] init];                            foo

foo = nil; // ==> Memory Leak                                            0x0




   Sven Günther                          http://www.it-agile.de                  5
Leaks finden




  Sven Günther   http://www.it-agile.de   6
iOS Reference Counting

 in iOS keine Garbage Collection
                   aber
 alle Objekte haben einen Referenzzähler (retainCount)
 wenn der retainCount 0 erreicht so wird der Speicher freigegeben




    Sven Günther               http://www.it-agile.de                7
iOS Reference Counting

 in iOS keine Garbage Collection
                   aber
 alle Objekte haben einen Referenzzähler (retainCount)
 wenn der retainCount 0 erreicht so wird der Speicher freigegeben




 //->retainCount+1

 alloc
 new
 retain
 copy



    Sven Günther               http://www.it-agile.de                7
iOS Reference Counting

 in iOS keine Garbage Collection
                   aber
 alle Objekte haben einen Referenzzähler (retainCount)
 wenn der retainCount 0 erreicht so wird der Speicher freigegeben




 //->retainCount+1                                      //->retainCount-1

 alloc                                                  release
                                                                      *
 new                                                    autorelease
 retain
 copy



    Sven Günther               http://www.it-agile.de                       7
iOS Reference Counting

 in iOS keine Garbage Collection
                   aber
 alle Objekte haben einen Referenzzähler (retainCount)
 wenn der retainCount 0 erreicht so wird der Speicher freigegeben




 //->retainCount+1                                      //->retainCount-1

 alloc                                                  release
                                                                      *
 new                                                    autorelease
 retain                     immer paarweise
 copy



    Sven Günther               http://www.it-agile.de                       7
Autoreleasepool


NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


                                                               Memory




                                                        pool


   Sven Günther                http://www.it-agile.de                   8
Autoreleasepool


NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


                                                                Memory

MyClass *foo = [[MyClass alloc] init];                   foo




                                                         pool


   Sven Günther                 http://www.it-agile.de                   8
Autoreleasepool


NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


                                                                Memory

MyClass *foo = [[MyClass alloc] init];                   foo

[foo autorelease];




                                                         pool   foo

    Sven Günther                http://www.it-agile.de                   8
Autoreleasepool


NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


                                                                Memory

MyClass *foo = [[MyClass alloc] init];                   foo

[foo autorelease];




[pool release];         ([foo release];)                 pool


    Sven Günther                http://www.it-agile.de                   8
Object-Ownership

Wer ist verantwortlich dafür Objekte zu releasen?

                      Object-Owner




    Sven Günther                http://www.it-agile.de   9
Object-Ownership

Wer ist verantwortlich dafür Objekte zu releasen?

                      Object-Owner

Wie wird man Object-Owner?

                      Bei Aufruf einer Methode,
                      die den retainCount erhöht.




    Sven Günther                http://www.it-agile.de   9
Object-Ownership

Wer ist verantwortlich dafür Objekte zu releasen?

                      Object-Owner

Wie wird man Object-Owner?

                      Bei Aufruf einer Methode,
                      die den retainCount erhöht.



Regel: Wer retained muss releasen!




    Sven Günther                http://www.it-agile.de   9
Factory-Methoden

Wie implementiere ich eine Factory-Methode?




   Sven Günther                http://www.it-agile.de   10
Factory-Methoden

Wie implementiere ich eine Factory-Methode?




          +(Foo*) fooWithName:(NSString*) name {

          
   Foo* [foo = [Foo alloc] init];

          
   return [foo autorelease];

          }




   Sven Günther                  http://www.it-agile.de   10
Vorsicht bei Zuweisungen




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          1

                                                           bar
                                                                          1




    Sven Günther                  http://www.it-agile.de                  11
Vorsicht bei Zuweisungen




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          1
 foo = bar;

                                                           bar
                                                                          1




    Sven Günther                  http://www.it-agile.de                  11
Vorsicht bei Zuweisungen




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          1
 foo = bar;

                                                           bar
                                                                          0
  …

 [foo release];




    Sven Günther                  http://www.it-agile.de                  11
Vorsicht bei Zuweisungen




 Foo *foo = [[Foo alloc] init];                                           Memory
 Foo *bar = [[Foo alloc] init];

                                                                    foo
                                                                                   1
 foo = bar;

                                                                    bar
                                                                                   0
  …

 [foo release];


 [bar release];                   crash!


    Sven Günther                           http://www.it-agile.de                  11
So ist es richtig




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          1

                                                           bar
                                                                          1




    Sven Günther                  http://www.it-agile.de                  12
So ist es richtig




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          0
 [foo release];
 foo = [bar retain];
                                                           bar
                                                                          2
                                                                          1




    Sven Günther                  http://www.it-agile.de                  12
So ist es richtig




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          0
 [foo release];
 foo = [bar retain];
                                                           bar
                                                                          1
 [foo release];




    Sven Günther                  http://www.it-agile.de                  12
So ist es richtig




 Foo *foo = [[Foo alloc] init];                                  Memory
 Foo *bar = [[Foo alloc] init];

                                                           foo
                                                                          0
 [foo release];
 foo = [bar retain];
                                                           bar
                                                                          0
 [foo release];



 [bar release];




    Sven Günther                  http://www.it-agile.de                  12
Implementierung von setter


// ivar Foo* foo;


-(void) setFoo:(Foo*) aFoo {

   foo = aFoo;
}




    Sven Günther               http://www.it-agile.de   13
Implementierung von setter


// ivar Foo* foo;


-(void) setFoo:(Foo*) aFoo {

   foo = aFoo;                                  Leak foo
}




    Sven Günther               http://www.it-agile.de       13
Implementierung von setter


// ivar Foo* foo;


-(void) setFoo:(Foo*) aFoo {

   foo = aFoo;                                  Leak foo
}

                                                 aFoo nicht retained




    Sven Günther               http://www.it-agile.de                  13
Implementierung von setter


// ivar Foo* foo;


-(void) setFoo:(Foo*) aFoo {
  [foo release];

    foo = [aFoo retain];
}




    Sven Günther               http://www.it-agile.de   14
Implementierung von setter


// ivar Foo* foo;


-(void) setFoo:(Foo*) aFoo {
  [foo release];                                 Was ist wenn

    foo = [aFoo retain];                        aFoo == foo?
}




    Sven Günther               http://www.it-agile.de           14
Implementierung von setter


     // ivar Foo* foo;

-(void) setFoo:(Foo*) aFoo {

   if (foo != aFoo) {

   
       [aFoo retain];                       Regel:

   
       [foo release];

   
       foo = aFoo;                          erst retain dann release

   }
}




    Sven Günther               http://www.it-agile.de                       15
Objective-C 2.0 Properties




 // @property (retain) Foo *foo;


 self.foo = aFooObject;




  Sven Günther                     http://www.it-agile.de   16
Objective-C 2.0 Properties




 // @property (retain) Foo *foo;


 self.foo = aFooObject;                              retainCount +1




  Sven Günther                     http://www.it-agile.de             16
Objective-C 2.0 Properties




 // @property (retain) Foo *foo;


 self.foo = aFooObject;                              retainCount +1




 self.foo = nil;




   Sven Günther                    http://www.it-agile.de             16
Objective-C 2.0 Properties




 // @property (retain) Foo *foo;


 self.foo = aFooObject;                              retainCount +1




                                                      retainCount -1
 self.foo = nil;




   Sven Günther                    http://www.it-agile.de              16
Achtung: Properties & alloc


// @property (retain) Foo *foo;



self.foo = [[Foo alloc] init];




    Sven Günther                  http://www.it-agile.de   17
Achtung: Properties & alloc


// @property (retain) Foo *foo;
                                                     alloc --> retainCount = 1
                                                     retain --> retainCount = 2
self.foo = [[Foo alloc] init];




    Sven Günther                  http://www.it-agile.de                      17
Achtung: Properties & alloc


// @property (retain) Foo *foo;
                                                     alloc --> retainCount = 1
                                                     retain --> retainCount = 2
self.foo = [[Foo alloc] init];




-(void) dealloc {                                    release --> retainCount = 1
      [foo release];
      [super dealloc];
}                                                    Leak!




    Sven Günther                  http://www.it-agile.de                      17
Achtung: Properties & alloc


// @property (retain) Foo *foo;
                                                        alloc --> retainCount = 1
                                                        retain --> retainCount = 2
self.foo = [[Foo alloc] init];




-(void) dealloc {                                       release --> retainCount = 1
      [foo release];
      [super dealloc];
}                                                       Leak!

                           gleiches gilt für

                           self.foo = [f copy];
                           self.foo = [f retain];
    Sven Günther                     http://www.it-agile.de                      17
Achtung: Properties & alloc




  // @property (retain) Foo *foo;                     alloc --> retainCount = 1
                                                      retain --> retainCount = 2
  Foo* f = [[Foo alloc] init];                        release --> retainCount = 1
  self.foo = f;
  [f release];


  …
  -(void) dealloc {
        [foo release];
                                                      release --> retainCount = 0
        [super dealloc];




   Sven Günther                     http://www.it-agile.de                     18
Verlassener Speicher (abandoned memory)




  Sven Günther      http://www.it-agile.de   19
Instruments allocations




  Sven Günther        http://www.it-agile.de   20
Ursachen für abandoned memory

 Tabellenzellen nicht wiederverwendet
 Caches
 Retain-Cycles




   Sven Günther                http://www.it-agile.de   21
RetainCycles




                 Foo


                                                  Bar *bar;
                                                  Foo *foo;
                                                  ..
                                                  bar.foo = [foo retain];
                                                  foo.bar = [bar retain];
                       Bar
                                                  // bar dealloc
                                                  -(void) dealloc {
                                                      [foo release];
                                                  }




  Sven Günther           http://www.it-agile.de                             22
RetainCycles




                 Foo
                                                  kein retain




                       Bar




  Sven Günther           http://www.it-agile.de                 23
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten




    Sven Günther                      http://www.it-agile.de   24
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten




    Sven Günther                      http://www.it-agile.de   24
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten


 Verantwortlichkeiten für Daten




    Sven Günther                      http://www.it-agile.de   24
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten


 Verantwortlichkeiten für Daten
     MasterViewController erzeugt Daten für DetailViewController




    Sven Günther                      http://www.it-agile.de        24
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten


 Verantwortlichkeiten für Daten
     MasterViewController erzeugt Daten für DetailViewController
     MasterViewController initialisiert DetailViewController mit den Daten




    Sven Günther                      http://www.it-agile.de                  24
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten


 Verantwortlichkeiten für Daten
     MasterViewController erzeugt Daten für DetailViewController
     MasterViewController initialisiert DetailViewController mit den Daten
     DetailViewController zeigt Daten an




    Sven Günther                      http://www.it-agile.de                  24
Master-Detail-Beziehungen

 Übliches Pattern in iOS: Master - Detail
     z.B. Ergebnisliste --> Detailansicht in Kontakten


 Verantwortlichkeiten für Daten
       MasterViewController erzeugt Daten für DetailViewController
       MasterViewController initialisiert DetailViewController mit den Daten
       DetailViewController zeigt Daten an
       Wenn DetailViewController releast wird, wird Speicher für DetailDaten freigegeben




    Sven Günther                      http://www.it-agile.de                                24
Globale Objekte

 Objekte die von allen anderen Objekten benutzt werden
    z.B. AppDelegate




   Sven Günther               http://www.it-agile.de      25
Globale Objekte

 Objekte die von allen anderen Objekten benutzt werden
     z.B. AppDelegate
 nicht als Datencontainer missbrauchen!




   Sven Günther                http://www.it-agile.de     25
Crashes

 Zugriff auf bereits freigegebenen Speicher
 Threading mit UIKit / CoreData
 Enumeration über mutable Collections




    Sven Günther                http://www.it-agile.de   26
Crashes bei Delegates




 Foo *foo;
                                          delegates werden i.d.R. nicht retained
 foo.delegate = bar;




   Sven Günther         http://www.it-agile.de                                     27
Crashes bei Delegates




 Foo *foo;
                                          delegates werden i.d.R. nicht retained
 foo.delegate = bar;



 [foo release]
                                           Vorsicht beim release des delegate
 [bar release];                            foo kann noch retained sein




   Sven Günther         http://www.it-agile.de                                     27
Crashes bei Delegates




 Foo *foo;
                                             delegates werden i.d.R. nicht retained
 foo.delegate = bar;



 [foo release]
                                              Vorsicht beim release des delegate
 [bar release];                               foo kann noch retained sein
 …


 // Foo:
 [delegate doSomething];

                            crash!



     Sven Günther          http://www.it-agile.de                                     27
Crashes bei Delegates




 Foo *foo;
                                             delegates werden i.d.R. nicht retained
 foo.delegate = bar;

 foo.delegate = nil;

 [foo release]
                                              Vorsicht beim release des delegate
 [bar release];                               foo kann noch retained sein
 …


 // Foo:
 [delegate doSomething];




     Sven Günther          http://www.it-agile.de                                     27
Threading

 Nicht alle Frameworks sind threadsafe
 UIKit
 Coredata




   Sven Günther                http://www.it-agile.de   28
UIKit

 Änderungen an der UI immer nur im MainThread
    [tableView reloadData] (nachdem Daten in Backgroundthread geladen wurden)




   Sven Günther                  http://www.it-agile.de                          29
UIKit

 Änderungen an der UI immer nur im MainThread
    [tableView reloadData] (nachdem Daten in Backgroundthread geladen wurden)




         -(void) updateUI {
         
   if (![NSThread isMainThread]) {
         
   
        [self performSelectorOnMainThread:@selector(updateUI)
         
   
       
      
    
   
     
    withObject:nil
         
   
       
      
    
   
     
  waitUntilDone:NO];
         
   
         return;
         
   }
         
   [tableView reloadData];
         }




   Sven Günther                      http://www.it-agile.de                      29
CoreData

 Änderungen an ManagedObjects nur im selben Thread durchführen, der das
  Objekt erzeugt hat
    insert in ManagedObjectContext
    fetch from perstistent store




   Sven Günther                   http://www.it-agile.de                   30
Mutable Collections





   NSMutableArray *strings;


   ...


   for (NSString *s in strings) {

   
      ...

   }




    Sven Günther                     http://www.it-agile.de   31
Mutable Collections





   NSMutableArray *strings;


   ...

   NSArray *stringsCopy = [strings copy];                     vor Enumeration Copy machen

   for (NSString *s in stringsCopy) {

   
      ...

   }

   [stringsCopy release];




    Sven Günther                      http://www.it-agile.de                           31
Simulator == Device?




  Sven Günther         http://www.it-agile.de   32
Simulator == Device?

 Speicher
    Device 256MB (512MB iPad2)
    Simulator unbegrenzt




   Sven Günther                   http://www.it-agile.de   32
Simulator == Device?

 Speicher
    Device 256MB (512MB iPad2)
    Simulator unbegrenzt
 CPU-Power
    Simulator nutzt die volle Power des Host-Rechners
    auf dem Device wird dann später die Performance nicht erreicht




   Sven Günther                    http://www.it-agile.de             32
Simulator == Device?

 Speicher
    Device 256MB (512MB iPad2)
    Simulator unbegrenzt
 CPU-Power
    Simulator nutzt die volle Power des Host-Rechners
    auf dem Device wird dann später die Performance nicht erreicht
 Unterschiedliche Implementierungen der SDK‘s
    zB [UIImage imageNamed:nil] (z.B. im iOS SDK 4.1)
    ==> Simulator: gibt nil zurück
    ==> Device: Crash




   Sven Günther                    http://www.it-agile.de             32
Simulator == Device?

 Speicher
    Device 256MB (512MB iPad2)
    Simulator unbegrenzt
 CPU-Power
    Simulator nutzt die volle Power des Host-Rechners
    auf dem Device wird dann später die Performance nicht erreicht
 Unterschiedliche Implementierungen der SDK‘s
    zB [UIImage imageNamed:nil] (z.B. im iOS SDK 4.1)
    ==> Simulator: gibt nil zurück
    ==> Device: Crash
 Leak-Detection
    ==> Simulator: keine Leaks gefunden
    ==> Device: Instruments findet Leaks




   Sven Günther                    http://www.it-agile.de             32

Weitere ähnliche Inhalte

Andere mochten auch

2ª reunión padres 4º orientación
2ª reunión padres 4º orientación2ª reunión padres 4º orientación
2ª reunión padres 4º orientaciónwebmontserrat
 
Presentación1
Presentación1Presentación1
Presentación1gafer25
 
Paraguay Asunción Central
Paraguay Asunción Central Paraguay Asunción Central
Paraguay Asunción Central 4298597
 
What are my goals
What are my goalsWhat are my goals
What are my goalsvofpoc
 

Andere mochten auch (9)

2ª reunión padres 4º orientación
2ª reunión padres 4º orientación2ª reunión padres 4º orientación
2ª reunión padres 4º orientación
 
Preguntas
Preguntas Preguntas
Preguntas
 
wiki pesentacion
wiki pesentacionwiki pesentacion
wiki pesentacion
 
Presentación1
Presentación1Presentación1
Presentación1
 
Paraguay Asunción Central
Paraguay Asunción Central Paraguay Asunción Central
Paraguay Asunción Central
 
1.- Diarios del C.T.E. Fase Intensiva
1.- Diarios del C.T.E. Fase Intensiva1.- Diarios del C.T.E. Fase Intensiva
1.- Diarios del C.T.E. Fase Intensiva
 
What are my goals
What are my goalsWhat are my goals
What are my goals
 
Erp
ErpErp
Erp
 
CUERPO HUMANO
CUERPO HUMANOCUERPO HUMANO
CUERPO HUMANO
 

Mehr von Sven Günther

Agile Transitionen mit Kanban - Meetup 20210317
Agile Transitionen mit Kanban - Meetup 20210317Agile Transitionen mit Kanban - Meetup 20210317
Agile Transitionen mit Kanban - Meetup 20210317Sven Günther
 
Was Manager über agile Entwicklungspraktiken wissen müssen
Was Manager über agile Entwicklungspraktiken wissen müssenWas Manager über agile Entwicklungspraktiken wissen müssen
Was Manager über agile Entwicklungspraktiken wissen müssenSven Günther
 
Mit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauenMit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauenSven Günther
 
Continuous Integration for iOS Developer
Continuous Integration for iOS DeveloperContinuous Integration for iOS Developer
Continuous Integration for iOS DeveloperSven Günther
 
iOS: Continuous Integration and One Click Deployments
iOS: Continuous Integration and One Click DeploymentsiOS: Continuous Integration and One Click Deployments
iOS: Continuous Integration and One Click DeploymentsSven Günther
 
iOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile WegiOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile WegSven Günther
 
iOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile WegiOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile WegSven Günther
 

Mehr von Sven Günther (7)

Agile Transitionen mit Kanban - Meetup 20210317
Agile Transitionen mit Kanban - Meetup 20210317Agile Transitionen mit Kanban - Meetup 20210317
Agile Transitionen mit Kanban - Meetup 20210317
 
Was Manager über agile Entwicklungspraktiken wissen müssen
Was Manager über agile Entwicklungspraktiken wissen müssenWas Manager über agile Entwicklungspraktiken wissen müssen
Was Manager über agile Entwicklungspraktiken wissen müssen
 
Mit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauenMit agilen Praktiken SOLIDe Systeme bauen
Mit agilen Praktiken SOLIDe Systeme bauen
 
Continuous Integration for iOS Developer
Continuous Integration for iOS DeveloperContinuous Integration for iOS Developer
Continuous Integration for iOS Developer
 
iOS: Continuous Integration and One Click Deployments
iOS: Continuous Integration and One Click DeploymentsiOS: Continuous Integration and One Click Deployments
iOS: Continuous Integration and One Click Deployments
 
iOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile WegiOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile Weg
 
iOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile WegiOS-Entwicklung - der agile Weg
iOS-Entwicklung - der agile Weg
 

Pitfalls bei der iOS-Entwicklung

  • 1. Pitfalls bei der iOS-Entwicklung Dipl.-Inform. (FH) Sven Günther Agiler Senior Softwareentwickler sven.guenther@it-agile.de - @iNevs http://www.it-agile.de
  • 2. About  Softwareentwickler seit 1997  erste Programmiersprache: C  Objective-C seit 2007  iOS Entwicklung seit 2009  Berater und Coach für agile Softwareentwicklung  gegründet 2005  Sitz in Hamburg und München  32 Mitarbeiter  Beratung, Schulung, Coaching in agilen Methoden  Scrum, Kanban, xTreme Programming  Develop With You  Develop 4 You Sven Günther http://www.it-agile.de 2
  • 3. Analyse der Crash-Reports  Speicherprobleme  Speicher ging aus  kein Response auf Memory-Warnings  System hat Programm abgeschossen Sven Günther http://www.it-agile.de 3
  • 4. Analyse der Crash-Reports  Speicherprobleme  Speicher ging aus  kein Response auf Memory-Warnings  System hat Programm abgeschossen  Crashes  Threading-Probleme  Zugriff auf freigegebenen Speicher Sven Günther http://www.it-agile.de 3
  • 5. Speicherverwaltung Sven Günther http://www.it-agile.de 4
  • 6. Speicherverwaltung  iPhone: 256MB RAM Sven Günther http://www.it-agile.de 4
  • 7. Speicherverwaltung  iPhone: 256MB RAM  Speicher ist begrenzt und daher kostbar Sven Günther http://www.it-agile.de 4
  • 8. Speicherverwaltung  iPhone: 256MB RAM  Speicher ist begrenzt und daher kostbar  im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden Sven Günther http://www.it-agile.de 4
  • 9. Speicherverwaltung  iPhone: 256MB RAM  Speicher ist begrenzt und daher kostbar  im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden Sven Günther http://www.it-agile.de 4
  • 10. Speicherverwaltung  iPhone: 256MB RAM  Speicher ist begrenzt und daher kostbar  im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden  Wie kann Speicher ausgehen? Sven Günther http://www.it-agile.de 4
  • 11. Speicherverwaltung  iPhone: 256MB RAM  Speicher ist begrenzt und daher kostbar  im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden  Wie kann Speicher ausgehen?  Leaks  Speicher auf den keine Referenz mehr besteht Sven Günther http://www.it-agile.de 4
  • 12. Speicherverwaltung  iPhone: 256MB RAM  Speicher ist begrenzt und daher kostbar  im Gegensatz zum Mac / PC kann kein virtueller Speicher genutzt werden  Wie kann Speicher ausgehen?  Leaks  Speicher auf den keine Referenz mehr besteht  Verlassener Speicher  Speicher der unnötig referenziert aber nicht mehr benutzt wird Sven Günther http://www.it-agile.de 4
  • 13. Leaks Was sind Leaks? Memory MyClass *foo = [[MyClass alloc] init]; foo 0x0 Sven Günther http://www.it-agile.de 5
  • 14. Leaks Was sind Leaks? Memory MyClass *foo = [[MyClass alloc] init]; foo foo = nil; // ==> Memory Leak 0x0 Sven Günther http://www.it-agile.de 5
  • 15. Leaks finden Sven Günther http://www.it-agile.de 6
  • 16. iOS Reference Counting  in iOS keine Garbage Collection aber  alle Objekte haben einen Referenzzähler (retainCount)  wenn der retainCount 0 erreicht so wird der Speicher freigegeben Sven Günther http://www.it-agile.de 7
  • 17. iOS Reference Counting  in iOS keine Garbage Collection aber  alle Objekte haben einen Referenzzähler (retainCount)  wenn der retainCount 0 erreicht so wird der Speicher freigegeben //->retainCount+1 alloc new retain copy Sven Günther http://www.it-agile.de 7
  • 18. iOS Reference Counting  in iOS keine Garbage Collection aber  alle Objekte haben einen Referenzzähler (retainCount)  wenn der retainCount 0 erreicht so wird der Speicher freigegeben //->retainCount+1 //->retainCount-1 alloc release * new autorelease retain copy Sven Günther http://www.it-agile.de 7
  • 19. iOS Reference Counting  in iOS keine Garbage Collection aber  alle Objekte haben einen Referenzzähler (retainCount)  wenn der retainCount 0 erreicht so wird der Speicher freigegeben //->retainCount+1 //->retainCount-1 alloc release * new autorelease retain immer paarweise copy Sven Günther http://www.it-agile.de 7
  • 20. Autoreleasepool NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Memory pool Sven Günther http://www.it-agile.de 8
  • 21. Autoreleasepool NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Memory MyClass *foo = [[MyClass alloc] init]; foo pool Sven Günther http://www.it-agile.de 8
  • 22. Autoreleasepool NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Memory MyClass *foo = [[MyClass alloc] init]; foo [foo autorelease]; pool foo Sven Günther http://www.it-agile.de 8
  • 23. Autoreleasepool NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Memory MyClass *foo = [[MyClass alloc] init]; foo [foo autorelease]; [pool release]; ([foo release];) pool Sven Günther http://www.it-agile.de 8
  • 24. Object-Ownership Wer ist verantwortlich dafür Objekte zu releasen? Object-Owner Sven Günther http://www.it-agile.de 9
  • 25. Object-Ownership Wer ist verantwortlich dafür Objekte zu releasen? Object-Owner Wie wird man Object-Owner? Bei Aufruf einer Methode, die den retainCount erhöht. Sven Günther http://www.it-agile.de 9
  • 26. Object-Ownership Wer ist verantwortlich dafür Objekte zu releasen? Object-Owner Wie wird man Object-Owner? Bei Aufruf einer Methode, die den retainCount erhöht. Regel: Wer retained muss releasen! Sven Günther http://www.it-agile.de 9
  • 27. Factory-Methoden Wie implementiere ich eine Factory-Methode? Sven Günther http://www.it-agile.de 10
  • 28. Factory-Methoden Wie implementiere ich eine Factory-Methode? +(Foo*) fooWithName:(NSString*) name { Foo* [foo = [Foo alloc] init]; return [foo autorelease]; } Sven Günther http://www.it-agile.de 10
  • 29. Vorsicht bei Zuweisungen Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 1 bar 1 Sven Günther http://www.it-agile.de 11
  • 30. Vorsicht bei Zuweisungen Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 1 foo = bar; bar 1 Sven Günther http://www.it-agile.de 11
  • 31. Vorsicht bei Zuweisungen Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 1 foo = bar; bar 0 … [foo release]; Sven Günther http://www.it-agile.de 11
  • 32. Vorsicht bei Zuweisungen Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 1 foo = bar; bar 0 … [foo release]; [bar release]; crash! Sven Günther http://www.it-agile.de 11
  • 33. So ist es richtig Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 1 bar 1 Sven Günther http://www.it-agile.de 12
  • 34. So ist es richtig Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 0 [foo release]; foo = [bar retain]; bar 2 1 Sven Günther http://www.it-agile.de 12
  • 35. So ist es richtig Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 0 [foo release]; foo = [bar retain]; bar 1 [foo release]; Sven Günther http://www.it-agile.de 12
  • 36. So ist es richtig Foo *foo = [[Foo alloc] init]; Memory Foo *bar = [[Foo alloc] init]; foo 0 [foo release]; foo = [bar retain]; bar 0 [foo release]; [bar release]; Sven Günther http://www.it-agile.de 12
  • 37. Implementierung von setter // ivar Foo* foo; -(void) setFoo:(Foo*) aFoo { foo = aFoo; } Sven Günther http://www.it-agile.de 13
  • 38. Implementierung von setter // ivar Foo* foo; -(void) setFoo:(Foo*) aFoo { foo = aFoo; Leak foo } Sven Günther http://www.it-agile.de 13
  • 39. Implementierung von setter // ivar Foo* foo; -(void) setFoo:(Foo*) aFoo { foo = aFoo; Leak foo } aFoo nicht retained Sven Günther http://www.it-agile.de 13
  • 40. Implementierung von setter // ivar Foo* foo; -(void) setFoo:(Foo*) aFoo { [foo release]; foo = [aFoo retain]; } Sven Günther http://www.it-agile.de 14
  • 41. Implementierung von setter // ivar Foo* foo; -(void) setFoo:(Foo*) aFoo { [foo release]; Was ist wenn foo = [aFoo retain]; aFoo == foo? } Sven Günther http://www.it-agile.de 14
  • 42. Implementierung von setter // ivar Foo* foo; -(void) setFoo:(Foo*) aFoo { if (foo != aFoo) { [aFoo retain]; Regel: [foo release]; foo = aFoo; erst retain dann release } } Sven Günther http://www.it-agile.de 15
  • 43. Objective-C 2.0 Properties // @property (retain) Foo *foo; self.foo = aFooObject; Sven Günther http://www.it-agile.de 16
  • 44. Objective-C 2.0 Properties // @property (retain) Foo *foo; self.foo = aFooObject; retainCount +1 Sven Günther http://www.it-agile.de 16
  • 45. Objective-C 2.0 Properties // @property (retain) Foo *foo; self.foo = aFooObject; retainCount +1 self.foo = nil; Sven Günther http://www.it-agile.de 16
  • 46. Objective-C 2.0 Properties // @property (retain) Foo *foo; self.foo = aFooObject; retainCount +1 retainCount -1 self.foo = nil; Sven Günther http://www.it-agile.de 16
  • 47. Achtung: Properties & alloc // @property (retain) Foo *foo; self.foo = [[Foo alloc] init]; Sven Günther http://www.it-agile.de 17
  • 48. Achtung: Properties & alloc // @property (retain) Foo *foo; alloc --> retainCount = 1 retain --> retainCount = 2 self.foo = [[Foo alloc] init]; Sven Günther http://www.it-agile.de 17
  • 49. Achtung: Properties & alloc // @property (retain) Foo *foo; alloc --> retainCount = 1 retain --> retainCount = 2 self.foo = [[Foo alloc] init]; -(void) dealloc { release --> retainCount = 1 [foo release]; [super dealloc]; } Leak! Sven Günther http://www.it-agile.de 17
  • 50. Achtung: Properties & alloc // @property (retain) Foo *foo; alloc --> retainCount = 1 retain --> retainCount = 2 self.foo = [[Foo alloc] init]; -(void) dealloc { release --> retainCount = 1 [foo release]; [super dealloc]; } Leak! gleiches gilt für self.foo = [f copy]; self.foo = [f retain]; Sven Günther http://www.it-agile.de 17
  • 51. Achtung: Properties & alloc // @property (retain) Foo *foo; alloc --> retainCount = 1 retain --> retainCount = 2 Foo* f = [[Foo alloc] init]; release --> retainCount = 1 self.foo = f; [f release]; … -(void) dealloc { [foo release]; release --> retainCount = 0 [super dealloc]; Sven Günther http://www.it-agile.de 18
  • 52. Verlassener Speicher (abandoned memory) Sven Günther http://www.it-agile.de 19
  • 53. Instruments allocations Sven Günther http://www.it-agile.de 20
  • 54. Ursachen für abandoned memory  Tabellenzellen nicht wiederverwendet  Caches  Retain-Cycles Sven Günther http://www.it-agile.de 21
  • 55. RetainCycles Foo Bar *bar; Foo *foo; .. bar.foo = [foo retain]; foo.bar = [bar retain]; Bar // bar dealloc -(void) dealloc { [foo release]; } Sven Günther http://www.it-agile.de 22
  • 56. RetainCycles Foo kein retain Bar Sven Günther http://www.it-agile.de 23
  • 57. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten Sven Günther http://www.it-agile.de 24
  • 58. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten Sven Günther http://www.it-agile.de 24
  • 59. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten  Verantwortlichkeiten für Daten Sven Günther http://www.it-agile.de 24
  • 60. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten  Verantwortlichkeiten für Daten  MasterViewController erzeugt Daten für DetailViewController Sven Günther http://www.it-agile.de 24
  • 61. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten  Verantwortlichkeiten für Daten  MasterViewController erzeugt Daten für DetailViewController  MasterViewController initialisiert DetailViewController mit den Daten Sven Günther http://www.it-agile.de 24
  • 62. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten  Verantwortlichkeiten für Daten  MasterViewController erzeugt Daten für DetailViewController  MasterViewController initialisiert DetailViewController mit den Daten  DetailViewController zeigt Daten an Sven Günther http://www.it-agile.de 24
  • 63. Master-Detail-Beziehungen  Übliches Pattern in iOS: Master - Detail  z.B. Ergebnisliste --> Detailansicht in Kontakten  Verantwortlichkeiten für Daten  MasterViewController erzeugt Daten für DetailViewController  MasterViewController initialisiert DetailViewController mit den Daten  DetailViewController zeigt Daten an  Wenn DetailViewController releast wird, wird Speicher für DetailDaten freigegeben Sven Günther http://www.it-agile.de 24
  • 64. Globale Objekte  Objekte die von allen anderen Objekten benutzt werden  z.B. AppDelegate Sven Günther http://www.it-agile.de 25
  • 65. Globale Objekte  Objekte die von allen anderen Objekten benutzt werden  z.B. AppDelegate  nicht als Datencontainer missbrauchen! Sven Günther http://www.it-agile.de 25
  • 66. Crashes  Zugriff auf bereits freigegebenen Speicher  Threading mit UIKit / CoreData  Enumeration über mutable Collections Sven Günther http://www.it-agile.de 26
  • 67. Crashes bei Delegates Foo *foo; delegates werden i.d.R. nicht retained foo.delegate = bar; Sven Günther http://www.it-agile.de 27
  • 68. Crashes bei Delegates Foo *foo; delegates werden i.d.R. nicht retained foo.delegate = bar; [foo release] Vorsicht beim release des delegate [bar release]; foo kann noch retained sein Sven Günther http://www.it-agile.de 27
  • 69. Crashes bei Delegates Foo *foo; delegates werden i.d.R. nicht retained foo.delegate = bar; [foo release] Vorsicht beim release des delegate [bar release]; foo kann noch retained sein … // Foo: [delegate doSomething]; crash! Sven Günther http://www.it-agile.de 27
  • 70. Crashes bei Delegates Foo *foo; delegates werden i.d.R. nicht retained foo.delegate = bar; foo.delegate = nil; [foo release] Vorsicht beim release des delegate [bar release]; foo kann noch retained sein … // Foo: [delegate doSomething]; Sven Günther http://www.it-agile.de 27
  • 71. Threading  Nicht alle Frameworks sind threadsafe  UIKit  Coredata Sven Günther http://www.it-agile.de 28
  • 72. UIKit  Änderungen an der UI immer nur im MainThread  [tableView reloadData] (nachdem Daten in Backgroundthread geladen wurden) Sven Günther http://www.it-agile.de 29
  • 73. UIKit  Änderungen an der UI immer nur im MainThread  [tableView reloadData] (nachdem Daten in Backgroundthread geladen wurden) -(void) updateUI { if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO]; return; } [tableView reloadData]; } Sven Günther http://www.it-agile.de 29
  • 74. CoreData  Änderungen an ManagedObjects nur im selben Thread durchführen, der das Objekt erzeugt hat  insert in ManagedObjectContext  fetch from perstistent store Sven Günther http://www.it-agile.de 30
  • 75. Mutable Collections NSMutableArray *strings; ... for (NSString *s in strings) { ... } Sven Günther http://www.it-agile.de 31
  • 76. Mutable Collections NSMutableArray *strings; ... NSArray *stringsCopy = [strings copy]; vor Enumeration Copy machen for (NSString *s in stringsCopy) { ... } [stringsCopy release]; Sven Günther http://www.it-agile.de 31
  • 77. Simulator == Device? Sven Günther http://www.it-agile.de 32
  • 78. Simulator == Device?  Speicher  Device 256MB (512MB iPad2)  Simulator unbegrenzt Sven Günther http://www.it-agile.de 32
  • 79. Simulator == Device?  Speicher  Device 256MB (512MB iPad2)  Simulator unbegrenzt  CPU-Power  Simulator nutzt die volle Power des Host-Rechners  auf dem Device wird dann später die Performance nicht erreicht Sven Günther http://www.it-agile.de 32
  • 80. Simulator == Device?  Speicher  Device 256MB (512MB iPad2)  Simulator unbegrenzt  CPU-Power  Simulator nutzt die volle Power des Host-Rechners  auf dem Device wird dann später die Performance nicht erreicht  Unterschiedliche Implementierungen der SDK‘s  zB [UIImage imageNamed:nil] (z.B. im iOS SDK 4.1)  ==> Simulator: gibt nil zurück  ==> Device: Crash Sven Günther http://www.it-agile.de 32
  • 81. Simulator == Device?  Speicher  Device 256MB (512MB iPad2)  Simulator unbegrenzt  CPU-Power  Simulator nutzt die volle Power des Host-Rechners  auf dem Device wird dann später die Performance nicht erreicht  Unterschiedliche Implementierungen der SDK‘s  zB [UIImage imageNamed:nil] (z.B. im iOS SDK 4.1)  ==> Simulator: gibt nil zurück  ==> Device: Crash  Leak-Detection  ==> Simulator: keine Leaks gefunden  ==> Device: Instruments findet Leaks Sven Günther http://www.it-agile.de 32

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. AutoreleasePool\n\nObjectOwnership\n\nFactorymethoden\n
  17. AutoreleasePool\n\nObjectOwnership\n\nFactorymethoden\n
  18. AutoreleasePool\n\nObjectOwnership\n\nFactorymethoden\n
  19. AutoreleasePool\n\nObjectOwnership\n\nFactorymethoden\n
  20. AutoreleasePool\n\nObjectOwnership\n\nFactorymethoden\n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. weitere Ursachen finden im Code\n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n