所以我有一个在Foo.h中定义的类,在Foo.m中实现。然后我有一个名为FooController.h / m的控制器,它有多种方法将Foo与视图连接起来。
Foo有多个属性,所以我只想引用三个定义为
// Foo.h
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSNumber *level;
@property (strong, nonatomic) Foo1 *foo1;
正如你所看到的,Foo有一个我在别处定义的Foo1类属性。我没有完成Foo1的实现,但基本上它只是一组定义的更多属性。 (我没有为Foo1定义任何init方法。这可能是个问题吗?)你应该留在脑后的Foo1的一个属性是:
// Foo1.h
@property (strong, nonatomic) NSString*name;
定义了以下Foo方法:
// Foo.m
-(id) initWithName:(NSString *)name
level:(NSNumber *)level
foo1:(Foo1 *)foo1
{
self = [super init];
if (self) {
_name = name;
_level = level;
_foo1 = foo1;
return self;
}
return nil;
}
FooController的一个方法叫做makeRandomFoo,它生成一个通用名,随机级和一个静态定义的foo1实例(大小意义上的静态)。它的实现如下:
// FooController.h
#import "Foo.h"
#import "Foo1.h"
@interface FooController : NSObject
@property (strong, nonatomic) Foo *foo;
- (Foo *)makeRandomFoo:(Foo *)foo;
// FooContoller.m
#import <stdlib.h>
@implementation FooController
@synthesize foo = _foo;
- (Foo *)makeRandomFoo:(Foo *)foo
{
NSString *name = @"Random Foo 1";
NSNumber *level = [NSNumber numberWithInt:(rand() / 100)];
Foo1 *foo1 = [[foo1 alloc] init];
foo = [[foo alloc] initwithName:name
atLevel:level
withFoo1:foo1];
return foo;
}
然后在我的viewcontroller上,FooViewController.h / m,我创建了一个名为“Make Random Foo”的圆形rect按钮和三个名为“nameLabel”,“levelLabel”“foo1Label”的标签
在我展示“Make Random Foo”的方法(实现的底部)之前,我应该只显示我的vc的定义和实现:
// FooViewController.h
@class Foo;
@class FooController;
@interface FooViewController : UIViewController
@property (strong, nonatomic) Foo *foo;
@property (strong, nonatomic) FooController *fooController;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *levelLabel;
@property (weak, nonatomic) IBOutlet UILabel *foo1Label;
- (IBAction)randomizeButton;
// FooViewController.m
- (id)reloadView
{
self.nameLabel.text = self.pet.name;
self.levelLabel.text = [NSString stringWithFormat:@"%@",self.pet.level];
self.foo1Label.text = self.pet.foo1.name;
(remember when I told you about a property of foo1 called name?)
}
- (IBAction)randomizeButton
{
[self.petController makeRandomFoo:self.foo];
[self reloadView];
}
因此,当我运行代码并点击随机按钮时,名称和foo1标签保持空白,级别标签显示为(null)。 所有属性都是合成的,但我没有为它们编写定制的setter或getter。 你能救我一下吗?
我尝试尽可能具有描述性,但如果您有更多问题,请随时提出要求!
答案 0 :(得分:3)
您没有遵循内存管理规则,因为您正在将初始化参数直接分配给[Foo init]
中的实例变量。您需要使用(合成的)setter方法:
-(id) initWithName:(NSString *)name
level:(NSNumber *)level
foo1:(Foo1 *)foo1
{
self = [super init];
if (self) {
self.name = name;
self.level = level;
self.foo1 = foo1;
}
return self;
}
由于您的实现,实例变量未被保留,因此可能过早地被释放。我们现在不想过早的事吗?
编辑要实现您的setter方法(已使用头文件中的@property
关键字声明),您只需使用@synthensize
,就像使用{ FooController
已经:
@implementation Foo
@synthesize name = _name;
@synthesize level = _level;
@synthesize foo1 = _foo1;
-(id) initWithName:(NSString *)name
... etc ...
@end
编辑2 :再看一下之后,您似乎使用不同命名的参数调用[Foo init...]
方法。您还需要在将所有权传递给Foo1
时释放Foo
对象。通常,在创建和返回new
的新实例时,您需要使用名称Foo
启动此方法。
尝试此操作并在最后一行设置断点,看看是否可以检查Foo
的属性:
- (Foo *)newRandomFoo:(Foo *)foo
{
NSString *name = @"Random Foo 1";
NSNumber *level = [NSNumber numberWithInt:(rand() / 100)];
Foo1 *foo1 = [[foo1 alloc] init];
foo = [[foo alloc] initwithName:name
level:level
foo1:foo1];
[foo1 release];
return foo;
}
答案 1 :(得分:0)
根据我的猜测,这就是我认为你想要做的事情(你似乎已经在大多数情况下将“Pet”替换为“Foo”,但并不是所有的示例代码,所以很难遵循。为什么不只是发布您的真实代码?)
makeRandomFoo
不应该带参数,所以应该看起来像这样:
- (Foo *)makeRandomFoo
{
NSString *name = @"Random Foo 1";
NSNumber *level = [NSNumber numberWithInt:(rand() / 100)];
Foo1 *foo1 = [[Foo1 alloc] init];
Foo *foo = [[Foo alloc] initwithName:name
atLevel:level
withFoo1:foo1];
return foo;
}
当你从视图控制器调用它时,看起来你真的想用你的“随机”替换视图控制器的foo
,所以它应该是:
- (IBAction)randomizeButton
{
self.foo = [self.petController makeRandomFoo];
[self reloadView];
}
最后,根据Foo1
的实现,name
属性将不包含任何内容,除非您在访问者中有默认值,因为您所做的只是分配/启动它而您拥有说你没有重写的init方法。