Что не так с и extern NSMutableArray? - PullRequest
2 голосов
/ 21 июня 2010

Так что я много читаю.И я наконец смог объявить внешний MutableArray и получить к нему доступ из разных представлений.У меня есть два представления: 1) Тестирование View Controller 2) Test2

Я объявляю массив следующим образом: TestingViewController.h

extern NSMutableArray *myArray;

#import <UIKit/UIKit.h>

@interface TestingViewController : UIViewController {

}

Я инициализирую массив при загрузке TestingViewController.Затем я могу добавить к нему объекты из теста 2 следующим образом: Test2.m

#import "Test2.h"

NSMutableArray *myArray;
@implementation Test2

-(IBAction)addToArray{
 [myArray addObject:@"Hot like Mexico"];
 NSLog(@"Object was added to Array! Count: %d",[myArray count]);
}

Кажется, он работает из обоих представлений.Количество и объекты постоянны даже при переключении.

Что я хочу знать, что с этим не так?Я знаю, что многие опытные программисты ненавидят глобальные переменные, но единственный способ заставить их работать - это как выше и через AppDelegate (я не хочу делать это таким образом).Просто пытаюсь быть более эффективным, добавляя массивы из нескольких видов и манипулируя ими.

Спасибо, ребята!

Ответы [ 4 ]

2 голосов
/ 21 июня 2010

Если вам действительно нужен «глобальный» объект, вот простой шаблон, который я использую довольно часто - ну, не очень, потому что у меня не так много глобалов.

Решите, к какому классу вы хотите, чтобы он принадлежал. Скажем, Test2 - это логический класс для его помещения. Создайте метод в Test2 для доступа к переменной. (может быть методом класса или методом экземпляра) следующим образом:

@interface Test2 : NSObject
{
    // ivars
}

+(NSMutableArray*) myArray;  // could also be an instance method

@end

@implementation Test2

+(NSMutableArray*) myArray
{
    static NSMutableArray* theValue = nil;
    @synchronized([Test2 class]) // in a single threaded app you can omit the sync block
    {
        if (theValue == nil)
        {
            theValue = [[NSMutableArray alloc] init];
        }
    }
    return theValue;
}
@end

Редактировать: Используя метод класса, чтобы получить доступ к myArray из любого места, просто сделайте это:

#import "Test2.h"

// To use class method, send messages to the class itself

[[Test2 myArray] addObject: @"foo bar"];
id foo = [[Test2 myArray] objectAtIndex: 0];
1 голос
/ 21 июня 2010

Похоже, вам нужен синглтон. http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html

1 голос
/ 21 июня 2010

Глобальные переменные - это кошмары, когда дело доходит до управления памятью, и это действительно не типичный способ сделать что-то с точки зрения дизайна. Правильный способ сделать это - объявить myArray как свойство в TestingViewController, а затем получить доступ к этому свойству из Test2.

1 голос
/ 21 июня 2010

Проблема с глобальными переменными в том, что они размножаются. Сначала у вас есть один, затем вам нужен другой, и, прежде чем вы это знаете, у вас есть десятки глобальных переменных, вы не уверены, где переменные инициализируются и освобождаются, и каждое изменение занимает вечность, потому что вы не знаете, каковы зависимости между компонентами.

Как правило, вы хотите иметь определенного владельца для каждого ресурса в программе. В приложении Какао различные объекты контроллера и делегата обеспечивают естественную иерархию ответственности за различные части проекта.


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

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

...