【问题标题】:Why does 'self' protect memory space?为什么“自我”保护内存空间?
【发布时间】:2009-09-26 18:42:01
【问题描述】:

在基于导航的应用程序中,我在我的应用程序委托中初始化了一个数组,而不使用 self.在 RootViewController 的 cellForRowAtIndexPath: 中访问时,所有数组对象都在那里,我可以看到它是一个 NSCFArray。加载应用程序后,我单击一个表格单元格并在 didSelectRowAtIndexPath: 中,该数组的类型为 NSArray,没有对象,并且出现 EXC_BAD_ACCESS 错误。如果我在应用程序委托中将数组放在 self 之前,一切都很好。这是为什么呢?

以下是应用委托 .h 文件:

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {

  UIWindow *window;
  UINavigationController *navigationController;
  NSMutableDictionary *aDict;
  NSArray *aArray;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSArray *aArray;
@property (nonatomic, retain) NSArray *aDict
@end

数组和字典在 .m 文件中合成。我在应用程序委托 .m 文件中初始化数组,如下所示:

aArray = [self.aDict allKeys];

在两个根控制器方法中都是这样访问的:

theDelegate = [[UIApplication sharedApplication] delegate]; 
[theDelegate.aArray objectAtIndex:2];

只有当我到达 didSelectRowAtIndexPath: 时它才会失败。在应用程序委托中执行此操作会使一切正常:

self.aArray = [self.aDict allKeys];

我没有对 cellForRowAtIndexPath: 和 didSelectRowAtIndexPath: 之间的 myArray 做任何事情。为什么在第一种情况下会失败?

【问题讨论】:

    标签: objective-c iphone xcode memory-management


    【解决方案1】:

    那是因为self.aArray 使用了综合属性。您将属性定义为(nonatomic, retain),这意味着无论它设置为什么,该值都将被保留。当您没有使用它时发生的事情是allKeys 正在自动释放,而当您实际使用它时,它已经消失了。使用该属性会保留该值,使其超出其范围。

    希望这是有道理的,如果我误解了你,请见谅。

    进一步阅读:

    我确信那里有更多对读者友好的文章,但现在您知道要查找什么了:Objective-C 内存管理和 Objective-C 属性。这很重要,所以我建议你这样做。

    【讨论】:

    • 谢谢。例如,为什么自动释放“仅”发生在两个根控制器方法之间,而不是在 cellForRowAtIndexPath: 之前? cellForRowAtIndexPath:已经访问过 aArray 两次(2 行)。是随机的吗?还有一件事:当你不使用'self'时,它(myArray)叫什么?使用'self'访问属性但不使用它意味着......
    • 不使用self就是直接设置。你真的必须阅读属性是如何工作的。属性只是设置变量的自动生成的方法,但以您定义的方式(保留、复制等)。如果您只是编写自己的 setter/getter 方法,您可能会有相同的行为,但属性会自动执行此操作,并且还允许您使用 self.something 语法。属性基本上只是为您节省一些繁重的工作、时间和冗余。
    • 是的,自动释放的对象可以被认为是随机释放的。实际上,它们通常在它们所在的池被释放时被释放,我建议你也阅读自动释放对象。池是 NSAutoreleasePool,我将在我的帖子中包含一个链接。所以它本身并不是完全随机的,但你不应该做出任何假设,而只是在这种情况下保留/复制。
    • 那么 4thSpace,我回答你的问题了吗?如果是这样,如果您接受答案,我将不胜感激。
    • 有没有办法强制这种行为?我已经设置了一个简单的应用程序,它使用上述场景而没有字典。所以应用程序委托上只有一个数组。我不能让它失败。访问实例变量时,我没有在应用程序委托中使用 self。
    猜你喜欢
    • 2022-08-16
    • 2012-02-12
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2015-05-14
    • 2011-07-05
    相关资源
    最近更新 更多