#xcode #macos #cocoa #xcode4 #osx-lion
#xcode #macos #cocoa #xcode4 #osx-lion
Вопрос:
Как я могу получить доступ @public NSArray
к нему или NSMutableArray
после его обновления? Из одного класса в другой?
Я могу получить к нему доступ с помощью вызова -(id)init
.. при запуске программы, но если я захочу обновить ее позже, я получаю ноль. В чем проблема?
Простой пример кода:
MyFirstClass.h
#import <Foundation/Foundation.h>
@interface MyFirstClass : NSObject
{
@public
NSArray *testArray;
}
-(IBAction)Button:(id)sender;
@end
MyFirstClass.m
#import "MyFirstClass.h"
@implementation MyFirstClass
- (id)init {
if (self = [super init]) {
//I can take this Array from here
//testArray = [NSArray arrayWithObjects: @"first", @"second", @"third", nil];
}
return self;
}
-(IBAction)Button:(id)sender {
//How take this Array?
testArray = [NSArray arrayWithObjects: @"first", @"second", @"third", nil];
}
@end
SimpleClass.h
#import <Foundation/Foundation.h>
#import "MyFirstClass.h"
@interface SimpleClass : NSObject
{
MyFirstClass *other;
}
-(IBAction)ButtonGet:(id)sender;
@end
SimpleClass.m
#import "SimpleClass.h"
#import "MyFirstClass.h"
@implementation SimpleClass
-(IBAction)ButtonGet:(id)sender {
other = [[MyFirstClass alloc] init];
if(other->testArray) {
NSLog(@"Working!");
}
else { NSLog(@"Not working!"); }
}
@end
Созданный пример имеет две кнопки в *.xib. Одна кнопка с именем «Button» (MyFirstClass) и другая «ButtonGet» (SimpleClass). Поэтому при запуске программы нужно нажать «Button», а затем «ButtonGet», после этого NSLog должен написать «Работает!», Если он получает testArray, а если нет — «Не работает!». Он всегда показывает «Не работает!».
Комментарии:
1. Пожалуйста, отредактируйте свой вопрос и опубликуйте код, в котором вы объявляете переменную экземпляра, где вы назначаете ей экземпляр массива и где вы пытаетесь его использовать. Кроме того, используете ли вы сборку мусора, ARC или ручное управление памятью?
2. Спасибо за ваш комментарий, я не использую сборку мусора, я использую ручное управление памятью.
3. Введите точку останова
awakeFromNib
, а оттуда щелкните правой кнопкой мышиtestArray
на панели отладчика и выберите «Наблюдать за переменной». Таким образом, при следующем изменении вашей переменной отладчик приостановит вашу программу.4. @zneak извините, я допустил ошибку, это не работает с awakeFromNib .. Это только wotks с — (id)init {…} . Может быть, вы знаете почему? может быть, что-то не так с возвратом?
Ответ №1:
Добро пожаловать в Objective C! Если вы чувствуете себя перегруженным и хотели бы прочитать некоторые вводные материалы, пожалуйста, взгляните на ссылки в превосходной карточке Питера Хоси «Полезные ссылки на какао / Cocoa Touch«.
Вы создаете MyFirstClass
экземпляр в -[SimpleClass ButtonGet:]
, и поскольку его testArray
член явно не назначен in -[MyFirstClass init]
, он (правильно) инициализируется нулем. Он останется таким навсегда, если вы не назначите ему что-то еще, но вы никогда этого не сделаете. (Вы назначаете ему только in [MyFirstClass Button:]
, но никогда не вызываете этот метод.)
Другие вещи, которые следует учитывать:
-
Ручное управление памятью требует, чтобы вы знали правила управления памятью Cocoa и постоянно учитывали их при написании кода. Например, вам нужно сохранить результат
[NSArray arrayWithObjects:]
, когда вы присваиваете его переменной-члену, и освободить его-[MyFirstClass dealloc]
. Аналогично, вам нужно освободитьother
объект внутри-[SimpleClass dealloc]
. -
Гораздо удобнее использовать свойства (объявленные с помощью) вместо прямого обращения к переменным-членам другого класса.
@property
-
Пожалуйста, подумайте о том, чтобы следовать рекомендациям по кодированию Cocoa и начинать имена методов со строчной буквы. Это позволяет вашему коду лучше соответствовать системным API-интерфейсам и значительно упрощает его чтение другими людьми.
Комментарии:
1. Большое вам спасибо за ваш ответ. Что вы имеете в виду, говоря «назначить ему что-то еще», можете ли вы привести мне пример, как это сделать? Я вызываю это при нажатии кнопки, нет?
2. Вы присваиваете что-то переменной-члену с помощью оператора присваивания (
=
) — вы уже написали код, в котором это делается-[MyFirstClass Button:]
. Однако этот код никогда не выполняется в вашем примере. Чтобы вызвать метод, вы можете (например) вставить инструкцию[other Button:nil];
-[SimpleClass ButtonGet]
после созданияMyFirstClass
объекта, но перед проверкойtestArray
. Есть ли кнопка? Вы не упомянули ни одной кнопки в своем вопросе.3. Есть две кнопки -(IBAction) Button: и -(IBAction) ButtonGet:, извините, я не упомянул об этом. Итак, я выполняю этот код при нажатии кнопки «Button», нет? И из другого класса другая кнопка «ButtonGet»
4. Мой пример сценария: созданный пример приложения имеет две кнопки в *.xib. Одна кнопка с именем «Button» (MyFirstClass) и другая «ButtonGet» (SimpleClass). Поэтому при запуске программы нужно нажать «Button», а затем «ButtonGet», после этого NSLog должен написать «Работает!», Если он получает testArray, а если нет — «Не работает!». Он всегда показывает «Не работает!».
5. Введите точку останова или NSLog,
-[MyFirstClass Button:]
чтобы убедиться, что он действительно выполняется — вероятно, он неправильно подключен в xib. Вам также необходимо исправить проблему с нераспределенным членом, иначеtestArray
он будет освобожден почти сразу, и у вас будет указатель, указывающий в никуда.