BKObject是一个自定义对象,我想将多个BKObject放入数组中。
BKViewController:
#import <UIKit/UIKit.h>
#import "BKObject.h"
@interface BKViewController : UIViewController
@property (strong, nonatomic) NSArray *data;
@property (weak, nonatomic) BKObject *tmpObject;
@end
BKViewController.m:
#import "BKViewController.h"
@implementation BKViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *arr = [[NSMutableArray alloc] init];
for(NSInteger i = 0; i < 100000; i++){
[arr addObject:[[BKObject alloc] initWithName:@""]];
}
self.data = [NSArray arrayWithArray:arr];
__weak BKObject *weakMutableObject = arr[0];
[arr removeAllObjects];
NSLog(@"%@", weakMutableObject); // print out the object, why?
__weak BKObject *weakObject = self.data[0];
self.data = nil;
NSLog(@"%@", weakObject); // print out the object again, but why?
self.tmpObject = [[BKObject alloc] initWithName:@""];
NSLog(@"%@", self.tmpObject); // print null, very clear
}
@end
我很好奇为什么前2条NSLog消息显示一个对象而不是null(就像在最后一个NSLog中一样)。我正在将最新的Xcode 5.0.1与iOS 7 SDK配合使用。
NSMutableArray *arr = [[NSMutableArray alloc] init];
for(NSInteger i = 0; i < 100000; i++){
[arr addObject:[[BKObject alloc] initWithName:@""]];
}
好的,因此,在这一点上,我们将一堆对象保留在一个数组中。
self.data = [NSArray arrayWithArray:arr];
至此,我们已经将一堆对象保留在两个不同的数组中。
__weak BKObject *weakMutableObject = arr[0];
[arr removeAllObjects];
NSLog(@"%@", weakMutableObject); // print out the object, why?
因为由指向的对象arr[0]
也由保留self.data
。
__weak BKObject *weakObject = self.data[0];
self.data = nil;
NSLog(@"%@", weakObject); // print out the object again, but why?
这个有点有趣。“问题”是arrayWithArray:
添加了一个额外的保留/自动释放,由于它们是平衡的,因此可以自由执行。您可以通过在不同点耗尽自动释放池来简单地演示这一点。
这显示了一个活动对象:
__weak NSObject *weakObject;
self.data = [NSArray arrayWithArray:arr]; // Note outside nested autorelease pool
@autoreleasepool {
...
weakObject= self.data[0];
self.data = nil;
}
NSLog(@"%@", weakObject); // print out the object
这显示nil:
__weak NSObject *weakObject;
@autoreleasepool {
self.data = [NSArray arrayWithArray:arr]; // Note inside nested autorelease pool
...
weakObject= self.data[0];
self.data = nil;
}
NSLog(@"%@", weakObject); // print nil
这里的教训是,您不应假定对象将在自动释放块内的任何给定点处释放。这不是ARC的承诺。它仅承诺对象有效的最短时间。系统的其他部分可以随意连接平衡的保留/自动释放对,这将延迟释放,直到池耗尽为止。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句