цель-c: выделить против синтеза / сохранить - PullRequest
0 голосов
/ 27 апреля 2011

У меня вопрос новичка.Я хотел бы иметь доступ к UIView во всех частях моего кода (в отличие от одного метода / функции).

Поэтому я объявил его в разделе @interface

UIView *calendarView;

а затем @property (nonatomic, retain) UIView *calendarView.В @implementation у меня есть @synthesise calendarView.

Теперь я хотел бы определить кадр этого вида и закодировать следующее:

    CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
calendarView = [[UIView alloc] initWithFrame:calendarFrame];

Но мне сейчас интересно, если я делаюздесь что-то серьезно не так, так как calendarView уже был сохранен и синтезирован.Конечно, UIView alloc избыточен или даже обязан вызывать сбой приложения, так как я сталкиваюсь с проблемами с памятью, верно?

Так что я решил написать код вместо двух предыдущих строк, но это имело только эффектчто calendarView вообще не отображается:

[calendarView setFrame:CGRectMake(170, 8, 200, 50)];

Так что мой вопрос, действительно ли мне нужно выделить представление, прежде чем я смогу его использовать?Или есть еще одно решение?

Ответы [ 5 ]

2 голосов
/ 27 апреля 2011

вы можете сохранить объект только после того, как он у вас есть в памяти (то есть вы распределили его). Итак, приведенный ниже код верен и необходим.

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
calendarView = [[UIView alloc] initWithFrame:calendarFrame];//you have alloc'ed once

Теперь вы добавите этопосмотреть на parentView.Например, я нахожусь внутри реализации UIViewController ..

[self.view addSubView:calendarView];  //now only your retain takes place. //So now calenderView has to release twice..Once by you (since you alloced it) and once by viewcontroller (since it has retained it)...
[calendarView release];//we are releasing once but the object will not be removed from memory since it is retained by viewController..Our part in memory management is over..Now when this viewController get dealloced it releases 

Вы можете использовать этот calendarView во всей реализации этого UIViewController ..

-(void)dealloc{
 [super dealloc];//should be last in dealloc..Now the entire controller will be dealloced along with the calenderView which is retained by viewController and the memory will be freed for future uses..
}

Это некоторые полезные учебные пособия.понять, чем документация Apple .. Но читать документацию Apple тоже ..

http://ferasferas.wordpress.com/2010/12/05/introduction-to-memory-management-on-iphone/

http://iosdevelopertips.com/objective-c/memory-management.html

http://mauvilasoftware.com/iphone_software_development/2008/01/iphone-memory-management-a-bri.html

https://humblecoder.blogspot.com/2009/08/iphone-tutorial-memory-management.html

1 голос
/ 27 апреля 2011

Поэтому я объявил это в разделе @interface

справа, который просто резервирует место и метку для доступа к ивару с типом + name

а затем @property (nonatomic, retain) UIView * calendarView.

право, которое объявляет методы доступа (setter + getter) и операцию при синтезе

В @implementation у меня есть @synthesise calendarView.

, который определяет (реализует) методы доступа, объявленные объявлением свойства.

Теперь я хотел бы определить кадр этого представления и закодировать следующее:

...Но теперь мне интересно, делаю ли я что-то здесь серьезно, так как calendarView уже был сохранен и синтезирован.Конечно, UIView alloc избыточен или даже обязан вызывать сбой приложения, так как у меня проблемы с памятью, верно?

с одной стороны, управление памятью отключено:

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
UIView * view = [[UIView alloc] initWithFrame:calendarFrame];
self.calendarView = view; // use the setter, unless in init... or dealloc
[view release], view = 0;

два: у вас обычно не будет большой пользы при создании UIView.как правило, вы создаете его подкласс.

three (чтобы ответить на ваш вопрос): в этом нет ничего плохого.переменная будет nil, пока она не будет установлена.поле не является инициализированным по умолчанию для объявленного типа - ну, это так, но тип на самом деле является указателем, поэтому в результате он инициализируется нулем.Вы можете создать представление или передать его из другого места.до этой точки представление будет nil / NULL / 0.

Так что я хотел бы кодировать это вместо двух предыдущих строк, но это только привело к тому, что calendarView вообще не отображается:

[calendarView setFrame: CGRectMake (170, 8, 200, 50)];Итак, мой вопрос: действительно ли мне нужно распределить представление, прежде чем я смогу его использовать?Или есть еще одно решение?

, возвращаясь к пункту №2 более подробно: в большинстве случаев вы захотите создать подкласс.UIView / NSView не рисует по умолчанию, но его можно использовать как контейнер вида.поэтому, возможно, вы захотите начать с некоторых существующих подклассов, чтобы ознакомиться с системными представлениями.

, как только у вас появится дескриптор, попробуйте реализовать свои собственные подклассы и переопределить drawRect:.

многим новичкам нравится использовать Interface Builder (теперь интегрированный в Xc4) - редактор представлений WYSIWYG.

1 голос
/ 27 апреля 2011

Вы на самом деле не делаете ничего плохого в своем первом примере, кроме возможной утечки памяти. Вы просто ошибаетесь, полагая, что ваш calendarView уже сохранен, потому что именно так вы определили свое свойство, что неверно. Определение свойства «только сохранение» означает, что при вызове self.calendarView = someotherview, someotherview будет сохранено, старое значение в calendarView будет освобождено, а для calendarView будет установлено значение someotherview. Использование calendarView без self не предоставит вам никаких правил управления памятью, таких как свойство, и поэтому ваш первый пример в порядке. Возможно, вы захотите, чтобы ваш код выглядел больше так.

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
1 голос
/ 27 апреля 2011

Да,

Перед использованием UIView.

вам необходимо либо выделить, либо получить его из других источников (выпустить его в dealloc, потому что вы его сохранили)

Используйте ниже

   CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];

Прочитайте документацию Apple по управлению памятью.

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

1 голос
/ 27 апреля 2011

Синтезирование свойства фактически не создает объект для вас. Вам все еще понадобятся методы alloc и init.

В приведенном выше коде, если вы хотите использовать свойство, вы должны использовать self.calendarView, а не просто calendarView. (Выполнение последнего - это обход свойства и прямое использование переменной экземпляра, что обычно не то, что вам нужно, с возможным исключением в вашем dealloc методе.)

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

self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
...