Не удается добавить в NSMutableArray из SecondaryView - PullRequest
0 голосов
/ 13 июня 2010

Я искал и читал, но до сих пор не нашел конкретного ответа.

Вкратце: у меня есть приложение, в котором я объявляю NSMutableArray в своем AppDelegate для синтеза при загрузке приложения.(код ниже).У меня есть SecondaryViewController, вызывающий эту функцию, и он выводит строку, чтобы сообщить мне, каков размер массива.Каждый раз, когда я запускаю его, он выполняется, но не добавляет никаких объектов в массив.Как это исправить?

Файл AppDelegate.h

#import <UIKit/UIKit.h>

@class arrayTestViewController;

@interface arrayTestAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    arrayTestViewController *viewController;

    NSMutableArray *myArray3;
}

@property (nonatomic, retain) NSMutableArray *myArray3;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet arrayTestViewController *viewController;

-(void)addToArray3;

@end

Файл AppDelegate.m

#import "arrayTestAppDelegate.h"
#import "arrayTestViewController.h"

@implementation arrayTestAppDelegate

@synthesize window;
@synthesize viewController;
@synthesize myArray3;

#pragma mark -
#pragma mark Application lifecycle



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    myArray3 = [[NSMutableArray alloc] init];


    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}

-(void)addToArray3{

    NSLog(@"Array Count: %d", [myArray3 count]);
    [myArray3 addObject:@"Test"];
    NSLog(@"Array triggered from SecondViewController");
    NSLog(@"Array Count: %d", [myArray3 count]);


}

Файл SecondViewController.m

#import "SecondViewController.h"
#import "arrayTestAppDelegate.h"

@implementation SecondViewController



-(IBAction)addToArray{
    arrayTestAppDelegate *object = [[arrayTestAppDelegate alloc] init];
    [object addToArray3];
}

РЕДАКТИРОВАТЬ ***

Хорошо, вот что я попробовал:

arrayTestViewController.h

#import <UIKit/UIKit.h>
#import "SecondViewController.h"

@interface arrayTestViewController : UIViewController {
    NSMutableArray *myArray;
    @private NSMutableArray *myArray2;
}

-(IBAction)showArray;
-(IBAction)switchViews;
-(IBAction)addToArray;


@end

arrayTestViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    myArray2 = [[NSMutableArray alloc] init];
    SecondViewController.myArray2 = myArray2;
    //ERRORS:Accessing unknown 'setMyArray2:" class method.
    //object cannot be set - either readonly property or no setter found
}

-(IBAction)switchViews{
    SecondViewController *screen = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
    screen.myArray2 = self.myArray2;
    //ERROR:Accessing unknown 'myArray2' getter method.

    screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self presentModalViewController:screen animated:YES];
    [screen release];
}

SecondViewController.h

#import <UIKit/UIKit.h>
#import "arrayTestViewController.h"


@interface SecondViewController : UIViewController{
    NSMutableArray *myArray2;
}

@property (nonatomic, retain) NSMutableArray *myArray2;

-(IBAction)addToArray;
-(IBAction)switchBack;

@end

SecondViewController.m

#import "SecondViewController.h"
#import "arrayTestViewController.h"

@implementation SecondViewController
@synthesize myArray2;


-(IBAction)addToArray{  
    arrayTestViewController *object = [[arrayTestViewController alloc] init];
    [object addToArray2];

}

Это дает мне три ошибки (также прокомментированные в коде):

Доступ к неизвестному методу класса setMyArray2:Объект не может быть установлен - либо свойство только для чтения, либо не найден установщик. Доступ к неизвестному методу получения 'myArray2'.


Сначала я тоже пробовал это в SecondViewController, но результат тот же.

Спасибо за ваше предложение не хранить их в делегате:)

Как бы я это исправить, учитывая, что я изменяю его так, чтобы инициализировать массив в RootViewController, и я вызываю функцию изSecondViewController?

1 Ответ

3 голосов
/ 13 июня 2010
-(IBAction)addToArray{
    arrayTestAppDelegate *object = [[arrayTestAppDelegate alloc] init];
    [object addToArray3];
}

Приведенный выше код неверен. Вы не должны alloc 'делегировать приложение внутри контроллера представления. Мол, никогда. Когда-либо. (Кроме того, вы теряете память каждый раз, так как вы не связали свой alloc / init с release. Но я отвлекся ...)

Если вы хотите получить доступ к делегату приложения с ваших контроллеров представления, вы делаете это так:

arrayTestAppDelegate* delegate = (arrayTestAppDelegate*)[[UIApplication sharedApplication] delegate];
 [delegate addToArray];

Пока это отвечает на ваш вопрос, я настоятельно призываю вас не использовать делегат приложения в качестве держателя для глобальных переменных. Хотя создание массивов верхнего уровня и т. Д. В делегате приложения не так уж и плохо, вы должны передавать эти объекты по иерархии контроллера представления при создании каждого контроллера представления. Это чище в том смысле, что у вас нет действий, происходящих на расстоянии. (Долой одиночек!)

(P.S. В Какао принято, что имена классов начинаются с заглавных букв - arrayTestAppDelegate следует переименовать ArrayTestAppDelegate)

Edit:

Как бы это исправить, учитывая, что я изменяю его, чтобы инициализировать массив в RootViewController и вызывать функцию из SecondViewController?

Во-первых, объект, которому принадлежит объект, вероятно, должен отвечать за инициализацию объекта. Не помещайте свой массив в делегат приложения, а затем инициализируйте его в другом месте. Это еще одна форма «действия на расстоянии», которую потом трудно прочитать и отладить.

Во-вторых, для ответа на ваш вопрос действительно требуется больше информации о том, как ваши "RootViewController" и "SecondViewController" существуют в иерархии вашего контроллера. Но я могу дать вам общий ответ о передаче объектов (например, вашего массива) вдоль линии.

(я предполагаю, что ваш RootViewController является контроллером представления верхнего уровня в вашем приложении, а SecondViewController является контроллером представления, показанным RootViewController. Судя по названиям, это безопасная ставка.)

ArrayTestAppDelegate.h (обратите внимание на заглавные буквы) может выглядеть примерно так:

...
@interface ArrayTestAppDelegate : NSObject <UIApplicationDelegate>
{
    ...
@private
    NSMutableArray* theArray;
    ...
}
...

Обратите внимание на отсутствие @property.

ArrayTestAppDelegate.m может выглядеть примерно так:

...
@implementation ArrayTestAppDelegate
...
- (void)applicationDidFinishLaunching:(UIApplication*)application
{
    ...
    theArray = [[NSMutableArray alloc] init];
    ...
    rootViewController.theArray = theArray;

    [window addSubview:rootViewController.view];
    [window makeKeyAndVisible];
}
...
- (void)dealloc
{
    [theArray release];
}
...
@end

RootViewController.h

...
@interface RootViewController : UITabBarController
{
    ...
    NSMutableArray* theArray;
    ...
}
...
@property (nonatomic, retain) NSMutableArray* theArray;
...

RootViewController.m

@implementation RootViewController
...
@synthesize theArray;
...
- (void)dealloc
{
    [theArray release];
}
...
- (void)showSecondViewController
{
    SecondViewController* secondViewController = [[SecondViewController alloc] initWithNib:@"SecondView"];
    secondViewController.theArray = self.theArray;
    // Show secondViewController here -- modally, using nav controller stack, etc.
    [secondViewController release];
}
...
@end

И так далее. Я оставляю читателю упражнение по реализации theArray @property для SecondViewController (подсказка: очень похоже на RootViewController)

...