Objective-c代码中的潜在问题

时间:2012-02-23 15:02:13

标签: objective-c

这是一小段代码。由俄罗斯公司Yandex发布,作为他们采访的一部分。这里有什么潜在的问题?它看起来很简单,应该是我看不到的隐藏问题。

第一个标题

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

- (NSString*) str;
@end

另一个档案

//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

最后一个文件

//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;
}

3 个答案:

答案 0 :(得分:6)

在另一个档案中:

@implementation
执行什么?必须指定。

在最后一个文件中:

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

这会崩溃,本地变量Foo objA没有被初始化,它可以设置为nil,因为在目标c中,nil的消息是正常的,但事实并非如此。

下面:

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

该方法将发出编译警告,因为该方法未在接口中声明,但它仍将调用该方法。

下面:

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

字符串@“number:”

缺少@

下面:

objB = objC;

你刚刚泄露了objB,因为现在没有有效的引用来释放之前的分配。

[objA release];

这从未分配过!

[objB release];

[objC release];

第二个会崩溃,因为它们都引用同一个对象,并且保留计数只有1。

第一个文件也有一些潜在的问题,例如声明一个似乎是getter的方法而没有声明ivar的属性,与setter相同,最好只声明一个属性。

答案 1 :(得分:1)

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

您无法在此处定义static int i = 0;。类型名称不允许指定存储类Foo.h

答案 2 :(得分:0)

此外,setter需要释放前一个字符串并保留新字符串。

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