困惑为啥在Objective C中一段代码有效而另一段代码无效
Posted
技术标签:
【中文标题】困惑为啥在Objective C中一段代码有效而另一段代码无效【英文标题】:Confused why one piece of code works and another doesn't in Objective C困惑为什么在Objective C中一段代码有效而另一段代码无效 【发布时间】:2010-10-12 11:32:58 【问题描述】:很抱歉标题非常模糊,我是 Objective C 的新手,并且在使用它时遇到了一些困难。基本上我有以下代码部分:
Graph *graph1 = [[Graph alloc] init];
[graph1 addNode:@"TEST"];
这在一定程度上起作用。但我想更改它,因为上面的代码发生在按下按钮时,因此我假设我每次执行此操作时都会创建一个新的“*graph1”。我想我可以简单地把它改成这样:
if(self = [super init])
[self setGraph: [[Graph alloc] init]];
return self;
上面在init方法中,下面是修改后的函数:
[graph addNode:@"TEST"];
但是在调试时我发现 addNode 方法永远不会像这样被调用。
谢谢 扎克
这是 testViewController.h
#import <UIKit/UIKit.h>
@class Graph;
@class Node;
@interface testViewController : UIViewController
Graph *graph;
UILabel *label;
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) Graph *graph;
- (IBAction) buttonPressed:(id)sender;
@end
这是 textViewController.m
#import "testViewController.h"
#import "Graph.h"
@implementation testViewController
@synthesize label, graph;
- (id)init
if(self = [super init])
[self setGraph: [[Graph alloc] init]];
return self;
- (IBAction)buttonPressed:(id)sender
//Graph *graph1 = [[Graph alloc] init];
[graph addNode:@"TEST"];
Node *node1 = [[Node alloc] initWithLabel: @"LABEL"];
label.text = node1.label;
【问题讨论】:
只是为了清楚我已经合成了“图表”。 【参考方案1】:首先想到的是 graph 是 nil ,因此向它调用方法(发送消息)将不会产生任何结果。不需要的释放会导致 EXC_BAD_ACCESS,而这似乎并非如此。
我想您是在 UIViewController 子类中调用所有这些,对吧?你确定调用了正确的init吗?如果您使用的是 NIB,则应覆盖 -(id)initWithNibName:bundle: 并将代码放在那里。我猜代码可能在普通的 -(id)init 中,因为您调用的是 [super init] 而不是 [super initWithNibName:nameOrNil bundle:bundleOrNil],但是这样,如果初始化控制器使用 NIB,您的自定义代码永远不会被调用,因此 graph 为零。
顺便说一句,如果图形属性是(保留),您也会在 init 中导致内存泄漏。
【讨论】:
是的,我在 -(id)init 方法中调用它。我会尝试使用 -(id)initWithNibName:bundle: 好吧,我将不得不成为一个完整的菜鸟,并问我在哪里可以找到我的笔尖名称? 带有 xib 扩展名的文件。可能是@"testViewController" 您不需要调用 initWithNibName:bundle -- @sigsegv 建议这是您需要覆盖的 init 方法。它已经被你调用了,你的 init 没有被调用。 它通常在资源文件夹中,并且与您的 UIViewController 类具有相同的名称,但带有 .xib(是的,.xib)estension,但 UIViewController 不关心名称笔尖。您只需要定义一个 -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)bundle 方法并在其主体中调用超级实现。如果您使用的是 sdk“模板”应用程序之一,它可能从源代码中丢失,但如果您将新的 UIViewController 类添加到项目中,您会发现它已被注释。快速浏览一下就会清楚很多事情。【参考方案2】:我确定您现在已经解决了这个问题,但我同意“添加”是“未被调用”的原因是您的图形对象此时为 nil
我会说,首先在您的“addNode”调用周围放置一条测试消息
NSLog(@"We tried to add here");
[graph addNode:@"TEST"];
这将显示 add 正在被调用——我敢打赌。
然后,在您之前调用 add 调用之前初始化“graph”的地方,尝试有条件地初始化它:
if(graph == nil) graph = [[Graph alloc] init];
[graph addNode:@"TEST"];
注意,这一切都只是为了发现问题。最后我想说你在如何处理记忆方面遇到了一些挑战。您可能没有参考问题,但后来泄漏。根据这段代码的执行频率,这可能是个问题。
但至少您可以通过上述测试更轻松地解决您的问题。
【讨论】:
【参考方案3】:您是否在标题中声明了图形变量?即:Graph *graph;
和对应的@property (nonatomic, retain) Graph *graph;
然后我会这样做:
-(id) init
graph = [[Graph alloc] init];
[graph retain];
这可能会有所帮助(我认为它不会的唯一原因是因为 a)如果您的变量未声明,那么您将收到类似 graph may not respond to addNode
的警告,如果未保留,那么您的应用程序将崩溃当它运行时)......除此之外,我看不出会有什么问题。如果这不起作用,能否请您发布 .h 和 .m 文件中的所有代码?
【讨论】:
【参考方案4】:然后我会这样做:
-(id) init graph = [[Graph alloc] init]; [graph retain];
这可能会有所帮助
这会导致内存泄漏。 graph 指向的对象的保留计数将具有 2 的保留计数。不理想。如果您使用 retain 属性声明该属性,那么
[self setGraph:[[[Graph alloc] init] autorelease]];
应该这样做。我去 -
self.graph = [[[Graph alloc] init] autorelease];
addNode: 方法未被调用的原因可能有很多。在封闭的方法中设置断点,看看一切是否如你所愿。
【讨论】:
如果你正确释放它不会导致内存泄漏......如果有一个保留属性,那么不能保证在你调用变量时它仍然在记忆。经过一定数量的代码行后,目标 c 中的变量可能会被遗忘。当您尝试访问该变量时,这将导致错误。这可以通过向变量添加保留来排序。另外,我认为这可能是问题,但可能不是问题。以上是关于困惑为啥在Objective C中一段代码有效而另一段代码无效的主要内容,如果未能解决你的问题,请参考以下文章
对故事板和以编程方式推送 ios Objective C 感到困惑