Проблема с инициализацией объекта в Objective C - PullRequest
1 голос
/ 27 марта 2011

В качестве демонстрации своей проблемы я создал небольшой пример: я создал новое приложение на основе представления, затем добавил кнопку в 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, который не инициализируется, хотя я инициализирую этот NSArray в viewDidLoad. Как я мог заставить это работать для меня? Мне нужно инициализировать этот TaskGenerator после загрузки представления, а затем я буду использовать этот объект в различных методах. Пожалуйста, помогите мне с этой проблемой.

Ответы [ 3 ]

4 голосов
/ 27 марта 2011

Я предполагаю, что ваше приложение аварийно завершает работу с 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]);
}
0 голосов
/ 27 марта 2011

Ваше объявление @property создает метод установки, который правильно сохраняет объект. Но когда вы присваиваете непосредственно переменной экземпляра mathPictures, вы обходите установщик, поэтому массив не сохраняется. Вместо этого вы должны использовать точечный синтаксис для использования установщика свойств:

self.mathPictures = [NSArray arrayWithObjects:@"0.png",@"1.png",@"2.png",nil];
0 голосов
/ 27 марта 2011

Нужно ли выделять, когда вы объявляете mathPictures & 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] быть первая строка перед выполнением других задач?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...