Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Objective-C: Day 2

Jayson Basañes
July 17, 2012
110

Objective-C: Day 2

Jayson Basañes

July 17, 2012
Tweet

Transcript

  1. Class  Methods   @interface Photo : NSObject {! ! }!

    ! + (NSString *)defaultCaption;! ! @end   @implementation Photo! ! + (NSString *)defaultCaption! {! return @"Woe is me";! }! ! @end   class Photo { public static function getDefaultCaption() { return 'Woe is me'; } }  
  2. Class  Methods   NSString *defaultCaption = [Photo defaultCaption];! ! NSLog(@"The

    default caption is: %@", defaultCaption);   $defaultCaption = Photo::getDefaultCaption(); echo 'The default caption is: ' . $defaultCaption;  
  3. Common  Founda&on  Classes   •  NSString  /  NSMutableString   • 

    NSNumber   •  NSDate   •  NSDecimalNumber   •  NSArray  /  NSMutableArray   •  NSDic&onary  /  NSMutableDic&onary   •  NSSet  /  NSMutableSet  
  4. Primi&ve  Types   •  int  /  unsigned  int   • 

    long  /  unsigned  long   •  float   •  double   •  char   •  NSInteger,  NSUInteger,  CGFloat  
  5. Object  Lifecycle   •  Very  important  to  understand  even  if

     you’re   using  ARC   •  Improper  memory  management  will  lead  to   weird  crashes  and  bugs  
  6. Object  Crea&on   +alloc   – Allocate  memory   -­‐init  

    – Ini&alize  object   Photo *photo = [[Photo alloc] init];!
  7. Object  Destruc&on   •  Objects  will  be  destroyed  when  they

     are   released  and  are  no  longer  referenced.   Photo *photo = [[Photo alloc] init];! ! [photo release];   Object  will  be  destroyed  
  8. Reference  Coun&ng   •  [obj  retainCount]:  When  retainCount  is  0,

     the  object  will  be   destroyed.   •  Note  that  the  value  of  -­‐retainCount  is  not  reliable  for   debugging  purposes.   -­‐retainCount   NSString *mystr = [[NSString alloc] init];   +1   1   [mystr retain];   +1   2   [mystr release];   -­‐1   1   [mystr release];   -­‐1   0  
  9. Dealloc   •  When  the  object  is  destroyed,  the  -­‐dealloc

     method   will  be  called.   •  Always  call  [super  dealloc]  in  your  custom  -­‐dealloc   method.  This  is  the  only  place  where  you  are   allowed  to  call  -­‐dealloc.   •  Release  all  objects  that  your  object  owns  in  -­‐ dealloc.   Tip:  Add  NSLog()  calls  in  -­‐dealloc  if  you  want  to  be  sure  if  your  object   gets  destroyed.  
  10. Dealloc   @interface Photo : NSObject {! NSString *caption;! }!

    ! - (id)initWithCaption:(NSString *)caption;! ! @end   @implementation Photo! ! - (id)initWithCaption:(NSString *)aCaption! {! if ((self = [super init]))! caption = [aCaption retain];! return self;! }! ! - (void)dealloc { [caption release]; [super dealloc]; } ! @end   The  Photo  class  “owns”   cap&on  
  11. SeZer  Methods   - (void)setCaption:(NSString *)value! {! // Release the

    object pointed by caption! [caption release]; ! ! // Point caption to value and retain it.! // The –retainCount is now +1! caption = [value retain]; ! }   public function setCaption($value) { $this->caption = $value; }   The  Photo  class  is  now  “part-­‐owner”  of  value  
  12. Copy  instead  of  retain   •  Creates  a  copy  of

     an  object  that  you  “own”   •  Recommended  for  small  objects  like  NSString  and  NSNumber   •  Since  you  own  copied  objects,  you  should  be  the  one  to   release  it.   - (void)setCaption:(NSString *)value! {! // Release the object pointed by caption! [caption release]; ! ! // Create a copy of value. The -retainCount is now "1"! caption = [value copy]; ! }  
  13. Returning  newly  created  objects   - (NSString *)floweredCaption! {! NSString

    *ret = [[NSString alloc] initWithFormat:@"* %@ *", caption];! ! return ret; // Wrong: memory leak! }   - (NSString *)floweredCaption! {! NSString *ret = [[NSString alloc] initWithFormat:@"* %@ *", caption];! [ret release];! ! return ret; // Wrong: returning a deallocated object!! }  
  14. Returning  newly  created  objects   •  The  -­‐autorelease  method  releases

     an  object  but  not   instantly.   •  The  object  is  added  to  the  current  autorelease  pool         Autorelease   Autorelease  pool  (NSAutoreleasePool)   •  Tracks  objects  that  are  autoreleased  and  releases  all  of   them  when  the  pool  itself  is  released   •  UIKit  wraps  sets  an  autorelease  pool  on  every  event  (e.g.   buZon  click)  
  15. Returning  newly  created  objects   - (NSString *)floweredCaption! {! NSString

    *ret = [[NSString alloc] initWithFormat:@"* %@ *", caption];! [ret autorelease];! ! return ret; ! }   Correct:  
  16. Some  methods  that  return   autoreleased  objects   [NSString stringWithFormat:@"",

    ...];! ! [NSNumber numberWithInt:13];! ! [NSDictionary dictionaryWithObject:@"shiki" ! forKey:@"username"];! ! [NSArray arrayWithObjects:@"A", @"B", nil];  
  17. Proper&es   @interface Photo : NSObject {! NSUInteger userId;! NSString

    *caption;! }! ! - (NSUInteger)userId;! - (void)setUserId:(NSUInteger)userId;! ! - (NSString *)caption;! - (void)setCaption:(NSString *)value;! ! @end   The  old  standard  way  
  18. Proper&es   @interface Photo : NSObject {! ! }! !

    @property (nonatomic) NSUInteger userId; @property (nonatomic, retain) NSString *caption; ! @end! class Photo { private $_caption; private $_userId; public function setCaption($value) { $this->_caption = $value; } public function getCaption() { return $this->_caption; } ... }  
  19. Proper&es   Photo.m   #import "Photo.h"! ! @implementation Photo! !

    @synthesize caption; @synthesize userId; ! - (void)dealloc! {! [caption release];! ! [super dealloc];! }! ! @end  
  20. Proper&es   Photo *photo = [[Photo alloc] init];! photo.caption =

    @"My caption";! photo.userId = 13174;! ! [photo release];   $photo = new Photo(); $photo->setCaption('My caption'); $photo->setUserId(13174);  
  21. Proper&es   Photo *photo = [[[Photo alloc] init] autorelease];! !

    NSString *caption = [photo caption];! ! [photo setCaption:@"New caption"];   Tradi&onal  geZer  and  seZer  methods  are  s&ll  available.  
  22. Proper&es   @property (nonatomic, retain) NSString *caption;   •  Creates

     a  private  instance  variable  named  cap>on.   •  In  conjunc&on  with  @synthesize,  creates:   - (NSString *)caption! {! return caption;! }! ! - (void)setCaption:(NSString *)value! {! [caption release];! caption = [value retain];! }  
  23. Proper&es   You  are  allowed  to  override  the  generated  geZers

     and  seZers.   @implementation Photo! ! @synthesize caption;! @synthesize userId;! ! - (void)setCaption:(NSString *)value { [caption release]; caption = [NSString stringWithFormat:@"Wee %@", value]; [caption retain]; } ! - (void)dealloc! {! ...! }! ! @end  
  24. Proper&es   You  are  allowed  to  override  the  generated  geZers

     and  seZers.   Photo *photo = [[[Photo alloc] init] autorelease];! ! photo.caption = @"PicLyf";! ! NSLog(@"caption = %@", photo.caption);   caption = Wee PicLyf  
  25. Using  proper&es  inside  class  methods   - (NSString *)caption! {!

    return [NSString stringWithFormat:@"FuFu %@", caption];! }! ! - (void)printCaption! {! self.caption = @"PicLyf";! ! NSLog(@"%@", self.caption);! // Above will print "FuFu PicLyf"! ! NSLog(@"%@", caption);! // Above will print "PicLyf";! }  
  26. Read-­‐only  Proper&es   @interface Photo : NSObject ! ! @property

    (readonly) NSString *caption;! ! - (id)initWithCaption:(NSString *)caption;! ! @end   @implementation Photo! ! @synthesize caption;! ! - (id)initWithCaption:(NSString *)aCaption! {! if ((self = [super init])) ! caption = [aCaption retain];! return self;! }! ! - (void)dealloc! {! ...! }! ! @end  
  27. Read-­‐only  Proper&es   Photo *photo = [[[Photo alloc] initWithCaption:@"PicLyf"] autorelease];!

    ! NSLog(@"caption = %@", photo.caption);! ! photo.caption = @"Grr"; // Not allowed  
  28. Exercise   Improving  upon  the  previous  exercise,  create  a  base

     class  named  FUser  that   has  these  proper&es:     •  firstName  (String)   •  lastName  (String)   •  canCreateUsers  –  a  readonly  BOOL.  Returns  NO     •  fullName  –  Readonly.  returns  a  concatenated  firstName  and  lastName.  Use   +alloc  and  -­‐init  and  -­‐autorelease  in  this  case.   Create  a  subclass  of  FUser  named  FAdminUser.  For  FAdminUser,   canCreateUsers  should  be  YES.  The  fullName  property  should  append   “  (Admin)”.       Important:     •  The  fullName  property  should  make  use  of  the  returned  value  of  the   superclass  ([super  fullName]).