Форум программистов, компьютерный форум CyberForum.ru

Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
#1

Вызов объекта в keyDown - Objective-C

16.05.2013, 13:43. Просмотров 1261. Ответов 14
Метки нет (Все метки)

являясь новичком в обжекте встал в ступор в ситуации, когда у меня есть класс, в нем инициализируется объект и в нем же оверрайдится keyDown:


View.h
Objective-C
1
2
3
4
5
6
7
@interface View : NSView
 
@property (strong, nonatomic) NSString *string;
 
- (id)init;
 
@end

View.m
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@implementation View
 
@synthesize string;
 
- (id)init
{
self = [super init];
   if (self)
   {
       string = @"string";
   }
   return self;
}
 
- (void)keyDown:(NSEvent *)event
{
    if ([event keyCode] == 125)
    {
       NSLog(@"%@", string);
    }
}
 
@end

AppDelegate.m
Objective-C
1
2
3
4
5
6
7
8
@implementation AppDelegate
 
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    View *v = [[View alloc] init];
}
 
@end
и по нажатию кнопки я получаю null
нутром чую что пытаюсь вызвать неинициализириованную переменную совсем по другому адресу нежели [v string], но как сделать что бы заработало пока понять не могу.

подымите мне веки, пожалуйста.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.05.2013, 13:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вызов объекта в keyDown (Objective-C):

Бесконечный вызов KeyDown для формы - C#
поставил для формы KeyPreview = true; сделал в один поток вывод событий клавиатуры(так нужно), а основной поток отлавливает события и...

Вызов объекта - Delphi
Прошу помощи вот в каком деле: Имеется программа, которая решает физическую задачу. Мне нужно создать второй "unit" файл, который будет...

Вызов объекта по имени - C#
Пока что я ещё нуб в программировании и много чего не знаю. А ситуация такая. Random rnd = new Random(); У меня имеется 58 кнопок....

Вызов события у объекта - .NET
Всем привет ) Подскажите пожалуйста как мне вызвать например событие у listbox.items PreviewMouseDoubleClick из какого нибудь button?...

Вызов объекта из button - C#
как из одного батона в котором создан объект доступиться из другого батона первый батон List<Train> train1 = new List<Train>(3); ...

Вызов атрибута объекта в Java - Java SE
Создала класс cycle, в котором несколько атрибутов. Когда создаю массив mass элементов типа cycle и пытаюсь обратиться к каким-нибудь...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
mobidevelop
16.05.2013, 14:31
  #2

Не по теме:

Здесь была глупость, вызванная невнимательностью. А как удалить сообщение не нашел...

spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
16.05.2013, 16:52  [ТС] #3
ну вопрос решился убиванием @property (strong, nonatomic) NSString *string;
прописыванием NSString *string = nil; до вызова init

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@implementation View
 
NSString *string = nil;
 
- (id)init
{
self = [super init];
   if (self)
   {
       string = @"string";
   }
   return self;
}
 
- (void)keyDown:(NSEvent *)event
{
    if ([event keyCode] == 125)
    {
       NSLog(@"%@", string);
    }
}
 
@end
отсюда глупый вопрос:

получается в таком раскладе все вызовы string обращаются к единому указателю заданному глобально,
но почему при использовании @property методы обращались к разным указателям?
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,277
16.05.2013, 20:30 #4
Цитата Сообщение от spens Посмотреть сообщение
@implementation View
NSString *string = nil;
- (id)init
что это за подход?

верните все, как было в первом посте, только к свойству нужно обращаться с помощью указателя self

т.е вместо string, будет self.string

т.к. @property это не просто переменная, а набор методов мутаторов и аксессоров (get/set), потому вызывая self.string вы вызываете аксессор метод данного инстанса, на который указывает self
spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
16.05.2013, 20:36  [ТС] #5
Цитата Сообщение от Vorona Посмотреть сообщение
что это за подход?

верните все, как было в первом посте, только к свойству нужно обращаться с помощью указателя self

т.е вместо string, будет self.string

т.к. @property это не просто переменная, а набор методов мутаторов и аксессоров (get/set), потому вызывая self.string вы вызываете аксессор метод данного инстанса, на который указывает self
попробовал

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@synthesize string;
 
- (id)init
{
    self = [super init];
    if (self)
    {
        string = @"test";
    }
    return self;
}
 
- (void)keyDown:(NSEvent *)theEvent
{
    if ([theEvent keyCode] == 125)
    {
        NSLog(@"%@", self.string);
    }
}
по нажатию кнопки опять имею null
mobidevelop
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
16.05.2013, 20:38 #6
В 9-й строке еще бы self. приписать...
spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
16.05.2013, 20:53  [ТС] #7
Цитата Сообщение от mobidevelop Посмотреть сообщение
В 9-й строке еще бы self. приписать...
все равно null

Добавлено через 7 минут
я логически это вижу так:

keyDown принадлежит View который привязан к окну в интерфейс билдере и получается что инициализируется раньше чем проходит инициализация string и поэтому обращается еще к пустому указателю

Добавлено через 1 минуту
хотя тогда не понятно почему конструкция без @property инициализирует все нормально и все обращения идут по одному адресу
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,277
16.05.2013, 20:57 #8
рабочий код
Objective-C
1
2
3
4
5
@interface View : NSView
 
@property (strong, nonatomic) NSString *string;
 
@end
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@implementation View
 
@synthesize string;
 
- (id)init
{
   self = [super init];
   if (self)
   {
       self.string = @"string";
   }
   return self;
}
 
- (void)keyDown:(NSEvent *)event
{
    if ([event keyCode] == 125)
    {
       NSLog(@"%@", self.string);
    }
}
 
@end
Цитата Сообщение от spens Посмотреть сообщение
хотя тогда не понятно почему конструкция без @property инициализирует все нормально и все обращения идут по одному адресу
все объявления переменных\свойств должны происходить в рамках конструкции @interface /* ... */ @end
объявление внутри @implementation полная фигня и вообще забудьте о таком варианте

дерзайте
spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
16.05.2013, 21:05  [ТС] #9
копипаста
не работает

Objective-C
1
2
3
4
5
6
7
#import <Cocoa/Cocoa.h>
 
@interface View : NSView
 
@property (strong, nonatomic) NSString *string;
 
@end
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#import "View.h"
 
@implementation View
 
@synthesize string;
 
- (id)init
{
    self = [super init];
    if (self)
    {
        self.string = @"string";
    }
    return self;
}
 
- (void)keyDown:(NSEvent *)event
{
    if ([event keyCode] == 125)
    {
        NSLog(@"%@", self.string);
    }
}
 
- (BOOL)acceptsFirstResponder
{
    return YES;
}
 
- (BOOL)becomeFirstResponder
{
    return YES;
}
 
@end
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,277
16.05.2013, 21:05 #10
Цитата Сообщение от spens Посмотреть сообщение
keyDown принадлежит View который привязан к окну в интерфейс билдере и получается что инициализируется раньше чем проходит инициализация string и поэтому обращается еще к пустому указателю
используйте метод awakeFromNib

думал, что вы View создаете методом инит
вообще, если вам что-то кажется, поставьте брейкпоинт на init и посмотрите или дебаггер вообще остановиться на этом методе, тогда будете хотя бы знать вызвался он или нет
spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
16.05.2013, 23:40  [ТС] #11
чорт точно

Objective-C
1
2
3
4
- (void)awakeFromNib
{
    self.string = @"string";
}
и все работает

спасибо!

Добавлено через 2 часа 23 минуты
что-то я снова затупил.

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

View.m

добавляю
Objective-C
1
2
3
4
- (void)say
{
    NSLog(@"%@", self.string);
}
и в аппделегат

Objective-C
1
2
3
4
5
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    View *v = [[View alloc] init];
    [v say];
}
по нажатию кнопки все ок, а вызов через экземпляр класса снова null
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,277
17.05.2013, 02:55 #12
ну так теперь же вы создаете View с помощью метода init
т.е. чтобы сейчас в лог вывелось значение, нужно в методе init его присвоить

а вот если вы View просто привяжете к элементу в интерфейсбилдере и руками нигде не будете его инитить, то лучше делать инициализацию переменных членов класса в awakeFromNib, в этот момент все элементы ниб файла приконекчены и инициализированы, потому этот вариант более "безопасный", чем initWithCoder или initWithFrame, где некоторые IBOutlet переменные в ниб файле могут все еще равняться nil на данном этапе, а вы получите головную боль от неясности

подытожим:
в awakeFromNib вы делаете инициализацию, когда вьюшка создана в интерфейс билдере, а не с помощью initXXX методов
в initXXX методах вы делаете инициализацию, когда создаете вьюшку руками при помощи initXXX методов и руками кладете ее на основную вьюху или что там еще

Добавлено через 31 минуту
и вообще, я надеюсь вы понимаете, что View, которую вы создаете в интрефейс билдере и вью, которую вы создаете с помощью init метода в аппделегате, это две разные вью и между собой никак не связаны?
(вплане два разных инстанса одного и того же класса)
spens
0 / 0 / 0
Регистрация: 16.05.2013
Сообщений: 7
17.05.2013, 12:05  [ТС] #13
Цитата Сообщение от Vorona Посмотреть сообщение
ну так теперь же вы создаете View с помощью метода init
т.е. чтобы сейчас в лог вывелось значение, нужно в методе init его присвоить

а вот если вы View просто привяжете к элементу в интерфейсбилдере и руками нигде не будете его инитить, то лучше делать инициализацию переменных членов класса в awakeFromNib, в этот момент все элементы ниб файла приконекчены и инициализированы, потому этот вариант более "безопасный", чем initWithCoder или initWithFrame, где некоторые IBOutlet переменные в ниб файле могут все еще равняться nil на данном этапе, а вы получите головную боль от неясности

подытожим:
в awakeFromNib вы делаете инициализацию, когда вьюшка создана в интерфейс билдере, а не с помощью initXXX методов
в initXXX методах вы делаете инициализацию, когда создаете вьюшку руками при помощи initXXX методов и руками кладете ее на основную вьюху или что там еще

Добавлено через 31 минуту
и вообще, я надеюсь вы понимаете, что View, которую вы создаете в интрефейс билдере и вью, которую вы создаете с помощью init метода в аппделегате, это две разные вью и между собой никак не связаны?
(вплане два разных инстанса одного и того же класса)
да, понимаю что это разные экземпляры создаются, просто не понимаю путь как решить что бы переменная была доступна и так и так причем одна ее версия

все работает когда initWithFrame и awakeFromNib вместе

View.m

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@synthesize string;
 
- (void)awakeFromNib
{
    self.string = @"string";
}
 
- (id)initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];
    if (self)
    {      
        self.string = @"string";
    }
    return self;
}
 
- (void)say
{
    NSLog(@"%@", self.string);
    NSLog(@"%p", self.string);
}
 
- (void)keyDown:(NSEvent *)event
{
    if ([event keyCode] == 125)
    {
        NSLog(@"%@", self.string);
        NSLog(@"%p", self.string);
    }
}
AppDelegate.m

Objective-C
1
2
3
4
5
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    View *v = [[View alloc] initWithFrame:[[self window] frame]];
    [v say];
}
обращение идет к одному адресу и на первый взгляд все хорошо

но ведь это же костыль и криворукость?

Добавлено через 7 минут
или все таки это нормально?

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)awakeFromNib
{
    self.string = @"string";
}
 
- (id)init
{
    self = [super init];
    if (self)
    {      
        [self awakeFromNib];
    }
    return self;
}
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
17.05.2013, 13:00 #14
Цитата Сообщение от spens Посмотреть сообщение
да, понимаю что это разные экземпляры создаются, просто не понимаю путь как решить что бы переменная была доступна и так и так причем одна ее версия
static Вам в помощь. И в геттере проверку на существование указателя.

Если я правильно понял проблему...
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,277
17.05.2013, 21:34 #15
напишите метод для инициализации обычных переменных
Objective-C
1
2
3
4
5
- (void)initializeLocalVariables
{
    self.string = @"string";
    // ...
}
так же можно написать initializeUIElements для инициализации юайных элементов, чтобы разделить одни от других

и вызывайте его и там и там, избежите копипаста и разложите все по разным методам, по сути, - обычная процедура выделения метода
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.05.2013, 21:34
Привет! Вот еще темы с ответами:

Вызов COM объекта в 64 битной программе - C#
Есть устройства чтения отпечатков пальцев. Есть SDK в виде COM объекта. В 32 разрядной системе все нормально, но в 64 разрядной при попытки...

Вызов com-объекта из web-сервиса - .NET
возможно кто-нибудь сталкивался с такой проблемой: в VS 2003 возникает ошибка System.InvalidCastException при вызове из web-сервиса любого...

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

1C 8.x Вызов функции из другого объекта - 1С
Здравствуйте! Стандартная конфигурация 1С:Бугалтерия предприятия 2.0.60.4 Нужно в Документе СчетФактураВыданный вызвать функцию...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
17.05.2013, 21:34
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru