0

我有一个初学者的问题。我想在我的代码的所有部分(而不是单个方法/函数)中访问 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)];

所以我的问题是我是否真的需要先分配视图才能使用它?还是有另一种解决方案?

4

5 回答 5

2

只有在内存中拥有一个对象后才能保留它(即你已经分配了它)..所以下面给出的代码是正确的和需要的..

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 

你可以在这个 UIViewController 的整个实现中使用这个 calendarView。

-(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..
}

这些是一些有用的教程..比苹果的文档更容易理解..但是也阅读苹果的文档..

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

于 2011-04-27T12:38:08.540 回答
1

合成一个属性实际上并不为您实例化一个对象。你仍然需要你的 alloc 和 init 方法。

在上面的代码中,如果你想使用该属性,你应该使用self.calendarView而不是仅仅使用calendarView. (执行后者是绕过属性并直接使用实例变量,这通常不是您想要的,除了您的dealloc方法中可能的例外。)

您应该进行的最后一项更改:假设您的属性被标记为保留,它将处理将您的对象保持在自身周围。因此,您应该自动释放要放入其中的对象。试试这个:

self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
于 2011-04-27T12:33:31.817 回答
1

除了可能的内存泄漏之外,您在第一个示例中实际上没有做错任何事情。您只是错误地认为您的 calendarView 已被保留,因为这是您定义属性的方式,这是不正确的。将您的属性定义为仅保留意味着当您调用self.calendarView = someotherview,someotherview将被保留时,calendarView 中的旧值将被释放,然后 calendarView 将设置为someotherview。在没有 self 的情况下使用 calendarView 不会为您提供任何内存管理规则,例如属性,这就是您的第一个示例可以使用的原因。您可能希望您的代码看起来更像这样。

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
于 2011-04-27T12:34:34.140 回答
1

是的,

在使用UIView.

下面使用

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

阅读苹果文档以进行内存管理..

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

于 2011-04-27T12:37:17.470 回答
1

因此我在@interface 部分声明了它

对,这只是保留空间和标签来访问具有类型+名称的 ivar

然后@property(非原子,保留)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 通常不会有太多用处。通常,您将创建它的子类。

三(回答你的问题):这没有什么问题。变量将一直存在nil,直到它被设置。该字段没有为声明的类型默认初始化——嗯,它是,但类型实际上是一个指针,所以结果是它被初始化为 nil。您可以创建一个视图或从其他地方传递它。在此之前,视图将为 nil/NULL/0。

所以我虽然我应该编码这个而不是前两行,但它只具有根本不显示 calendarView 的效果:

[calendarView setFrame:CGRectMake(170, 8, 200, 50)]; 所以我的问题是我是否真的需要先分配视图才能使用它?还是有另一种解决方案?

更详细地回到第 2 点:在大多数情况下,您需要创建一个子类。UIView/NSView 默认不绘图,但可以作为视图容器使用。因此,您可能希望从一些现有的子类开始熟悉系统提供的视图。

一旦掌握了这一点,请尝试实现自己的子类并覆盖drawRect:.

许多初学者喜欢使用 Interface Builder(现在集成到 Xc4 中)——一个所见即所得的视图编辑器。

于 2011-04-27T12:43:42.997 回答