Objective-c:分配与综合/保留

发布于 2024-11-03 18:23:03 字数 727 浏览 2 评论 0原文

我有一个初学者的问题。我希望能够在代码的所有部分访问 UIView(而不是单个方法/函数)。

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

UIView *calendarView;

然后在 @property (nonatomic, keep) UIView *calendarView 中声明它。在@implementation 中,我有@synthesise calendarView

现在我想定义这个视图的框架并编写以下代码:

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

但是我现在想知道我在这里是否做了一些严重错误的事情,因为calendarView已经被保留和综合了。当然 UIView alloc 是多余的,甚至必然会使应用程序崩溃,因为我遇到了内存问题,对吗?

所以我虽然应该编码这个而不是前两行,但它只会产生日历视图根本不显示的效果:

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

所以我的问题是我是否真的需要在使用视图之前分配它?或者还有其他解决方案吗?

I have a beginner's question. I would like to have access to an UIView in all parts of my code (as opposed to a single method/function).

I therefore declared it in the @interface section

UIView *calendarView;

and then @property (nonatomic, retain) UIView *calendarView. In the @implementation I have @synthesise calendarView.

Now I would like to define the frame of this view and coded the following:

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

But I am now wondering if I am doing something seriously wrong here, as calendarView has already been retained and synthesised. Surely UIView alloc is superfluous or even bound to make the app crash, as I am running into memory problems, right?

So I though I should code this instead of the two previous lines, but it only had the effect that the calendarView is not shown at all:

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

So my question is if I really need to alloc the view before I can use it? Or is there yet another solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

策马西风 2024-11-10 18:23:03

您只能在将对象放入内存后保留该对象(即您已分配它)。所以下面给出的代码是正确且需要的。

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

现在您将将此视图添加到父视图中。例如,我在 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

you can retain an object only after you have it in memory(ie you have alloc'ed it)..So below given code is correct and needed..

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

now you will add this view to a parentView. For example I am inside a UIViewController implementation..

[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 

You can use this calendarView throughout the implementation of this 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..
}

These are some useful tutorials..easier to understand than apple's documentation..But read Apple's documentation too..

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

单调的奢华 2024-11-10 18:23:03

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

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

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

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

Synthesizing a property doesn't actually instantiate an object for you. You'll still need your alloc and init methods.

In the code above, if you're wanting to use the property, you should be using self.calendarView rather than just calendarView. (Doing the latter is bypassing the property and using the instance variable directly, which is usually not what you want, with the possible exception of in your dealloc method.)

The one final change you should make: given that your property is marked retain, it'll handle keeping your object around itself. Therefore you should autorelease the object you're putting into it. Try this:

self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
帅气称霸 2024-11-10 18:23:03

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

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

You actually are not doing anythin wrong in your first example other than a possible memory leak. You just have the wrong thinking that your calendarView is already retained because that was how you defined your property, which is not true. Defining your property as retain only means that when you call self.calendarView = someotherview, someotherview will be retained, the old value in calendarView will be released and calendarView will then be set to someotherview. Using calendarView without self will not provide you with any memory management rules like the property and that is why your first example is ok. You may want your code to look more like this.

CGRect calendarFrame = CGRectMake(170,     8, 200, 50);
self.calendarView = [[[UIView alloc] initWithFrame:calendarFrame] autorelease];
意中人 2024-11-10 18:23:03

是的,

在使用 UIView 之前,您需要分配或从其他来源获取它(在 dealloc 中释放它,因为您要保留它)。

使用下面的

   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

Yes,

You either need to alloc OR get it from others sources (release it in dealloc because you are retaining it ) before using UIView.

Use below

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

Read apple documentation for memory management..

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

桃扇骨 2024-11-10 18:23:03

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

右侧声明了它,它只保留空间和标签来访问具有类型+名称的 ivar

然后@property(非原子,保留)UIView *calendarView。

正确的,它声明了访问器(setter+getter),以及合成的操作

在@implementation中我有@synthesise calendarView。

定义(实现)属性声明所声明的访问器。

现在我想定义这个视图的框架并编码如下:

...
但我现在想知道我在这里是否做错了什么,因为calendarView已经被保留和综合了。当然,UIView 分配是多余的,甚至必然会使应用程序崩溃,因为我遇到了内存问题,对吧?

其一,你的内存管理已关闭:

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 setFrame:CGRectMake(170, 8, 200, 50)];
所以我的问题是我是否真的需要先分配视图才能使用它?或者还有其他解决方案吗?

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

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

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

I therefore declared it in the @interface section

right, that just reserves space and a label to access an ivar with the type+name

and then @property (nonatomic, retain) UIView *calendarView.

right, that declares the accessors (setter+getter), and operation if synthesized

In the @implementation I have @synthesise calendarView.

that defines (implements) the accessors declared by the property declaration.

Now I would like to define the frame of this view and coded the following:

...
But I am now wondering if I am doing something seriously wrong here, as calendarView has already been retained and synthesised. Surely UIView alloc is superfluous or even bound to make the app crash, as I am running into memory problems, right?

for one, your memory management is off:

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;

two:
you will not usually have much use in creating a UIView. typically, you will create a subclass of it.

three (to get to your question):
there's nothing wrong with that. the variable will be nil until it's been set. the field is not default initialized for the declared type -- well, it is, but the type is in fact a pointer, so the result is that it is initialized to nil. you can either create a view or pass it in from someplace else. the view will be nil/NULL/0 until that point.

So I though I should code this instead of the two previous lines, but it only had the effect that the calendarView is not shown at all:

[calendarView setFrame:CGRectMake(170, 8, 200, 50)];
So my question is if I really need to alloc the view before I can use it? Or is there yet another solution?

stepping back to point #2 in more detail: you'll want to create a subclass in most cases. UIView/NSView does no drawing by default, but it can be used as a view container. therefore, you may want to start with some existing subclasses to get familiar with the system-supplied views.

once you have a handle on that, try implementing your own subclasses and overriding drawRect:.

many beginners like using Interface Builder (now integrated into Xc4) -- a WYSIWYG view editor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文