TOP KEK
TOP KEK

Reputation: 2641

Potential problems in objective-c code

Here is a small piece of code. Posted by Russian company Yandex as a part of their interview. What are potential problems here? It looks very simple, should be hidden problems I can not see.

First header

//Foo.h
#import <Cocoa/Cocoa.h>
@interface Foo : NSObject
{
   NSString* str;
   static int i = 0;
}

- (NSString*) str;
@end

Another file

//Foo.m
#import "Foo.h"
@implementation
- (id) init
{
   return [self initWithStr:"number:" someInt:6];
}

- (id) initWithStr:(NSString*)theStr someInt:(int)value
{
   self = [super init];
   str = [NSString stringWithFormat:@"%@%d", theStr, value];
   return self;
}

- (NSString*) str
{
   return str;
}

- (void) setStr:(NSString*)theStr
{
   str = theStr;
}
@end

And the last file

//main.m
#import <Cocoa/Cocoa.h>
#import "Foo.h"
int main(int argc, char *argv[])
{
   Foo objA;
   NSLog([objA str]);
   [objA setStr:@"hello world!"];
   NSLog([objA str]);

   Foo* objB = [[Foo alloc] init];
   Foo* objC = [[Foo alloc] initWithStr:@"My magic number:" value:265];
   objB = objC;

   NSLog([objB str]);

   [objA release];
   [objB release];
   [objC release];

   return 0;
}

Upvotes: 1

Views: 3347

Answers (3)

Avi Cohen
Avi Cohen

Reputation: 3414

Also, the setter needs to release the previous string and retain the new one.

- (void) setStr:(NSString*)theStr
{
  if(str) {
    [str release];
  }
  str = [theStr retain];
}

Upvotes: 0

beryllium
beryllium

Reputation: 29767

@interface Foo : NSObject
{
   NSString* str;
   static int i = 0;
}

You cann't define static int i = 0; here. Type name does not allow storage class to be specified Foo.h

Upvotes: 1

Oscar Gomez
Oscar Gomez

Reputation: 18488

In another file:

@implementation

implementation of what? must specify.

In the last file:

Foo objA;
   NSLog([objA str]);
   [objA setStr:@"hello world!"];
   NSLog([objA str]);

This will crash, local variable Foo objA is not initialized, it would be fine it was set to nil, since messages to nil are ok in objective c but it is not.

Here:

 [objA setStr:@"hello world!"];

That method will give a compile warning since that method is not declared in the interface, but it will still call the method.

Here:

- (id) init
{
   return [self initWithStr:"number:" someInt:6];
}

Missing @ for the string @"number:"

Here:

objB = objC;

You just leaked objB, since there is now no valid reference to release the previous allocation.

[objA release];

This was never allocated!

[objB release];

[objC release];

The second one will crash since they both refer to the same object, and the retain count is only 1.

The first file also has some potential issues such as declaring a method that appears to be a getter without declaring a property for the ivar, same with the setter, would be better to just declare a property.

Upvotes: 6

Related Questions