ben*_*nck 4 memory-leaks objective-c nsmutablearray nsarray ios
BKObject 是一个自定义对象,我想将多个 BKObject 放入一个数组中。
BK视图控制器:
#import <UIKit/UIKit.h>
#import "BKObject.h"
@interface BKViewController : UIViewController
@property (strong, nonatomic) NSArray *data;
@property (weak, nonatomic) BKObject *tmpObject;
@end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我很好奇为什么前 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:@""]];
}
Run Code Online (Sandbox Code Playgroud)
好的,此时,我们有一堆由数组保留的对象。
self.data = [NSArray arrayWithArray:arr];
Run Code Online (Sandbox Code Playgroud)
现在,我们有一堆由两个不同数组保留的对象。
__weak BKObject *weakMutableObject = arr[0];
[arr removeAllObjects];
NSLog(@"%@", weakMutableObject); // print out the object, why?
Run Code Online (Sandbox Code Playgroud)
因为 by 指向的对象arr[0]也被 保留self.data。
__weak BKObject *weakObject = self.data[0];
self.data = nil;
NSLog(@"%@", weakObject); // print out the object again, but why?
Run Code Online (Sandbox Code Playgroud)
这个有点意思。“问题”是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
Run Code Online (Sandbox Code Playgroud)
这显示为零:
__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
Run Code Online (Sandbox Code Playgroud)
这里的教训是,您不应该假设对象将在自动释放块内的任何给定点释放。这并不是 ARC 的承诺。它仅承诺对象有效的最短时间。系统的其他部分可以随意附加平衡的保留/自动释放对,这将延迟释放,直到池耗尽。
| 归档时间: |
|
| 查看次数: |
6535 次 |
| 最近记录: |