4

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

4 回答 4

6

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

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

更新或使用 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 返回一个对象(在本例中为 an NSNumber),因此正确的语句是:

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

运行带有这些更正的程序会产生:

Retrieving Values 100, 200 
KVC Retrieveal  100 
于 2012-04-11T11:40:37.937 回答
6

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

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

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

于 2012-04-11T11:42:06.737 回答
1

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

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

        // you code

        return ...;
    }
}

编辑:
关于你的第二部分问题。valueForKey返回id,将其转换为int

NSLog (@" KVC Retrieveal  %i ", [[t valueForKey:@"x"] intValue]);
于 2012-04-11T11:42:16.420 回答
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];
}

可能会奏效

于 2012-04-11T11:46:25.017 回答