Objective c 为什么';自我';保护内存空间?

Objective c 为什么';自我';保护内存空间?,objective-c,iphone,xcode,memory-management,Objective C,Iphone,Xcode,Memory Management,在基于导航的应用程序中,我在应用程序委托中初始化数组,而不使用self。当在RootViewController的CellForRowatineXpath:中访问时,所有数组对象都在那里,我可以看到它是一个NSFarray。加载应用程序后,我单击一个表格单元格,在DidSelectRowatineXpath:,同一数组有一种NSArray类型,没有对象,我得到一个EXC_uuu坏访问错误。如果我在app委托中在数组前面加上self,一切都很好。为什么呢 下面是app delegate.h文件:

在基于导航的应用程序中,我在应用程序委托中初始化数组,而不使用self。当在RootViewController的CellForRowatineXpath:中访问时,所有数组对象都在那里,我可以看到它是一个NSFarray。加载应用程序后,我单击一个表格单元格,在DidSelectRowatineXpath:,同一数组有一种NSArray类型,没有对象,我得到一个EXC_uuu坏访问错误。如果我在app委托中在数组前面加上self,一切都很好。为什么呢

下面是app delegate.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
在两种根控制器方法中都是这样访问的:

theDelegate = [[UIApplication sharedApplication] delegate]; 
[theDelegate.aArray objectAtIndex:2];
只有当我到达didSelectRowAtIndexPath:时,它才会失败。在app delegate中执行此操作可使一切正常工作:

self.aArray = [self.aDict allKeys];

我没有对CellForRowatineXpath:和DidSelectRowatineXpath:之间的myArray执行任何操作。为什么在第一个场景中失败?

这是因为
self.aArray
使用了合成属性。您将属性定义为
(非原子,保留)
,这意味着无论它设置为什么,该值都将保留。当你不使用它时发生的事情是,
allKeys
被自动释放,当你实际使用它时,它已经不见了。使用属性保留该值,使其超出其范围

希望这是有道理的,如果我误解了你,对不起

进一步阅读:


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

这是因为
self.aArray
使用了合成属性。您将属性定义为
(非原子,保留)
,这意味着无论它设置为什么,该值都将保留。当你不使用它时发生的事情是,
allKeys
被自动释放,当你实际使用它时,它已经不见了。使用属性保留该值,使其超出其范围

希望这是有道理的,如果我误解了你,对不起

进一步阅读:


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

谢谢。为什么自动释放“仅”发生在两个根控制器方法之间,而不是在CellForRowatineXpath之前:例如?cellForRowAtIndexPath:已访问aArray两次(2行)。是随机的吗?还有一件事:当您不使用“self”时,它(myArray)的名称是什么?使用“self”访问属性,但不使用它意味着…不使用self只是直接设置它。你真的需要仔细阅读属性是如何工作的。属性只是自动生成的方法,用于设置变量,但使用您定义的方式(保留、复制等)。如果您只编写自己的setter/getter方法,您可能会有相同的行为,但是属性会自动执行此操作,并且还允许您使用self.something语法。属性基本上只是为您节省一些繁重的工作、时间和冗余。是的,自动释放的对象可以被认为是随机释放的。实际上,它们通常是在它们所在的池被释放时被释放的,我建议您也阅读一下自动释放的对象。该池是NSAutoreleasePool,我将在我的帖子中包含一个链接。所以这本身并不是完全随机的,但你不应该做任何假设,在这种情况下只保留/复制?如果是的话,如果你接受了答案,我会很感激。有没有办法强迫你这样做?我已经设置了一个简单的应用程序,它使用上述场景而不使用字典。因此,应用程序委托上只有一个数组。我不能让它失败。访问实例变量时,我没有在应用程序委托中使用self。谢谢。为什么自动释放“仅”发生在两个根控制器方法之间,而不是在CellForRowatineXpath之前:例如?cellForRowAtIndexPath:已访问aArray两次(2行)。是随机的吗?还有一件事:当您不使用“self”时,它(myArray)的名称是什么?使用“self”访问属性,但不使用它意味着…不使用self只是直接设置它。你真的需要仔细阅读属性是如何工作的。属性只是自动生成的方法,用于设置变量,但使用您定义的方式(保留、复制等)。如果您只编写自己的setter/getter方法,您可能会有相同的行为,但是属性会自动执行此操作,并且还允许您使用self.something语法。属性基本上只是为您节省一些繁重的工作、时间和冗余。是的,自动释放的对象可以被认为是随机释放的。实际上,它们通常是在它们所在的池被释放时被释放的,我建议您也阅读一下自动释放的对象。该池是NSAutoreleasePool,我将在我的帖子中包含一个链接。所以这本身并不是完全随机的,但你不应该做任何假设,在这种情况下只保留/复制?如果是的话,如果你接受了答案,我会很感激。有没有办法强迫你这样做?我已经设置了一个简单的应用程序,它使用上述场景而不使用字典。因此,应用程序委托上只有一个数组。我不能让它失败。访问实例变量时,我没有在应用程序委托中使用self。
self.aArray = [self.aDict allKeys];