作为我的问题的演示,我创建了一个小例子:我创建了新的基于视图的应用程序,然后我将按钮添加到xib并将其连接到IBAction。然后我写了这堂课:
#import <Foundation/Foundation.h>
@interface TaskGenerator : NSObject {
NSArray* mathPictures;
}
- (TaskGenerator*)init;
@property(retain,nonatomic) NSArray* mathPictures;
@end
#import "TaskGenerator.h"
@implementation TaskGenerator
@synthesize mathPictures;
- (TaskGenerator*)init
{
self = [super init];
if (self)
{
mathPictures = [NSArray arrayWithObjects:@"0.png",@"1.png",@"2.png",@"3.png",@"4.png",@"5.png",nil];
}
return self;
}
@end
然后我修改了创建的viewController:
#import <UIKit/UIKit.h>
#import "TaskGenerator.h"
@interface NechapackaViewController : UIViewController {
TaskGenerator *taskGen;
}
-(IBAction)vypis:(id)sender;
@property(nonatomic,retain) TaskGenerator *taskGen;
@end
#import "NechapackaViewController.h"
#import "TaskGenerator.h"
@implementation NechapackaViewController
@synthesize taskGen;
- (void)viewDidLoad {
taskGen = [[TaskGenerator alloc] init];
printf("%d\n",[taskGen.mathPictures count]);
[super viewDidLoad];
}
-(IBAction)vypis:(id)sender
{
printf("%d\n",[taskGen.mathPictures count]);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[super dealloc];
}
@end
我不明白为什么在点击按钮后,NSArray存在问题,虽然我在viewDidLoad中初始化了这个NSArray,但是没有初始化。我怎么能让它对我有用?我需要在加载视图后初始化此TaskGenerator,然后我将在各种方法中使用此对象。 请帮我解决这个问题。
答案 0 :(得分:4)
我假设你的应用程序崩溃了EXC_BAD_ACCESS。原因是mathPictures对象已被释放并且不再有效。您使用arrayWithObjects:
方法创建了它,该方法返回一个自动释放的对象。对象自动释放时,会将其添加到池中,当该池“耗尽”时,其中的每个对象都将收到release
消息。由于数组未在其他任何地方保留,因此将其解除分配,使mathPictures
变量指向空闲内存。要解决此问题,您需要使用alloc / init方法来获取保留的数组,或者在创建数组后自己保留数组。
- (TaskGenerator*)init {
self = [super init];
if (self) {
mathPictures = [[NSArray alloc] initWithObjects:@"0.png",@"1.png",@"2.png",@"3.png",@"4.png",@"5.png",nil];
}
return self;
}
另外,在viewDidLoad
方法中,您应该首先调用超级实现 。
- (void)viewDidLoad {
[super viewDidLoad];
taskGen = [[TaskGenerator alloc] init];
printf("%d\n",[taskGen.mathPictures count]);
}
答案 1 :(得分:0)
您的@property声明会创建一个正确保留对象的setter方法。但是,当您直接分配给mathPictures实例变量时,您绕过了setter,因此不会保留该数组。相反,您应该使用点语法来使用属性setter:
self.mathPictures = [NSArray arrayWithObjects:@"0.png",@"1.png",@"2.png",nil];
答案 2 :(得分:-1)
你申报mathPictures&amp;时需要分配吗? NSArray的:
NSArray *mathPictures = [[NSArray alloc] initWithObjects:@"0.png", @"1.png", @"2.png", ..., nil];
或者,您可以将以下行放在viewDidLoad中:
mathPictures = [[NSArray arrayWithObjects:@"0.png", @"1.png", @"2.png", ..., nil] retain];
另外,在viewDidLoad中,在执行其他任务之前,[super viewDidLoad]应该是第一行吗?