Objective C自动释放问题,代码有什么问题?

时间:2012-04-11 11:37:02

标签: objective-c

Objective-C的新手,

#import <objc/objc.h>
#import <Foundation/Foundation.h>

@interface Test:NSObject
{
  int x,y, abc;
  NSString *v1, *v2;
}
@property int x , y, abc;
-(void) print;

@end

@implementation Test
@synthesize x,y, abc;
-(void) print
{
 NSLog (@"v1 and v2 values %i, %i ", v1, v2);
}

@end

int main ( int argc, char **argv)

{
  Test *t = [[Test alloc] init];
  /* Synthesized Set Method */
  [t setX:100];
  [t setY:200];
 /* Synthesized Get Method */
  NSLog (@"Retrieving Values %i, %i ",[t x], [t y]);

 /* another Way to retrieve the throuhg KVC Model */
 NSLog (@" KVC Retrieveal  %i ", [t valueForKey:@"x"]);

}

我没有得到编译时错误,但是我得到了运行时错误:

2012-04-11 16:25:08.470 testpgm[22237] Retrieving Values 100, 200 
2012-04-11 16:25:08.513 testpgm[22237] autorelease called without pool for object (0x8e78ca0) of class NSMethodSignature in thread <NSThread: 0x8e23a08>
2012-04-11 16:25:08.514 testpgm[22237] autorelease called without pool for object (0x8e94610) of class NSIntNumber in thread <NSThread: 0x8e23a08>
2012-04-11 16:25:08.514 testpgm[22237]  KVC Retrieveal  149505552 

看起来它与内存问题有关。有人指出了这个问题吗?

注意:根据您的所有输入,我可以解决自动发布问题,但仍然

NSLog (@" KVC Retrieveal  %i ", [t valueForKey:@"x"]);

不会打印正确的值而是垃圾。我做错了吗?

4 个答案:

答案 0 :(得分:5)

主例程不会创建自动释放池。

根据您使用的版本和编译器,使用其中一种方法。

较新或使用ARC:

int main(int argc, char *argv[])
{
    @autoreleasepool {

    // your code

    }
}

int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

     // your code

    [pool drain];
}

代码还有许多其他问题,例如:

NSLog (@"v1 and v2 values %i, %i ", v1, v2);

应该是

NSLog (@"v1 and v2 values %@, %@ ", v1, v2);

%@用于打印对象,%i用于整数。

该行:

NSLog (@" KVC Retrieveal  %i ", [t valueForKey:@"x"]);

很有趣,因为valueForKey返回一个对象(在本例中为NSNumber),所以正确的语句是:

NSLog (@" KVC Retrieveal  %@ ", [t valueForKey:@"x"]);

使用这些更正运行程序会产生:

Retrieving Values 100, 200 
KVC Retrieveal  100 

答案 1 :(得分:5)

当您处于应用程序的运行循环中时,会为您创建一个默认的自动释放池。但是,当您使用自己的main运行时,需要在main的顶部手动创建自动释放池,并定期将其耗尽。

NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];
// Your code that uses autorelease...
[myPool drain];

如果您正在使用新的LLVM编译器进行编译,请改用新的@autoreleasepool功能。

答案 2 :(得分:1)

main函数必须具有自动释放池。

int main(int argc, char *argv[])
{
    @autoreleasepool {

        // you code

        return ...;
    }
}

修改
关于你的第二部分问题。 valueForKey返回id,将其投放到int

NSLog (@" KVC Retrieveal  %i ", [[t valueForKey:@"x"] intValue]);

答案 3 :(得分:0)

int main ( int argc, char **argv)

{
 NSAutoreleasePool *myPool = [NSAutoreleasePool new];
  Test *t = [[Test alloc] init];
  /* Synthesized Set Method */
  [t setX:100];
  [t setY:200];
 /* Synthesized Get Method */
  NSLog (@"Retrieving Values %i, %i ",[t x], [t y]);

 /* another Way to retrieve the throuhg KVC Model */
 NSLog (@" KVC Retrieveal  %i ", [t valueForKey:@"x"]);

 [pool drain];
}

可能会起作用