- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
为方便起见,我用一些工作代码编辑了上一篇文章。
以下代码 (ARC'ed) 似乎会泄漏,并会在短时间运行后使 sim 卡或设备崩溃:
#define kROWS 100
#define kCols 34
void run();
static ViewController *instance;
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *nsBackColor;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.nsBackColor = [NSMutableArray arrayWithCapacity:1];
instance = self;
// set up a '2D array'
for (int x = 0; x < kROWS; x++) {
[self.nsBackColor addObject:[NSMutableArray arrayWithCapacity:1]];
for (int y = 0; y < kCols; y++) {
[[self.nsBackColor objectAtIndex:x] addObject:[UIColor whiteColor]];
}
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
run();
});
}
- (void)plotColor:(UIColor *)color atX:(short)x andY:(short)y {
[[self.nsBackColor objectAtIndex:x] replaceObjectAtIndex:y withObject:color];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
void plot(short xLoc, short yLoc,
short backRed, short backGreen, short backBlue) {
@autoreleasepool {
[instance plotColor:[UIColor colorWithRed:((float)backRed/100)
green:((float)backGreen/100)
blue:((float)backBlue/100)
alpha:(float)1]
atX:xLoc andY:yLoc];
}
}
void run() {
short x = 0;
short y = 0;
short backRed = 0;
short backGreen = 0;
short backBlue = 0;
while (true) {
x++;
if (x >= kROWS) {
x = 0;
}
y++;
if (y >= kCols) {
y = 0;
}
backRed = arc4random() % 255;
backBlue = arc4random() % 255;
backGreen = arc4random() % 255;
plot(x, y, backRed, backGreen, backBlue);
usleep(1000);
}
}
如果我让它在设备或模拟器上运行足够长的时间(几分钟),我将收到 mmap malloc 错误 (sim) 或内存警告(设备)并崩溃。
通过 Instruments Allocations,我可以看到 +[UIColor colorWithRed:green:blue:alpha:] 开始膨胀,直到最终撞到内存墙。
我可以将 UIColor 分配给一个属性(直接或通过复制),比如 self.myColor = color,并且没有这样的泄漏。
我也可以这样做:
[[self.nsBackColor objectAtIndex:x] replaceObjectAtIndex:y withObject:[self description]];
我也遇到了同样的问题。
在我看来,数组中替换的对象(是的,这最初是作为一个 2D c 数组开始的,但我认为这是问题所在)永远丢失和泄漏并且没有正确释放。
这将是 Instruments-> 短时间运行后的分配:
如有任何帮助,我们将不胜感激,并可提供更多信息。
最佳答案
发生的事情是您在每次迭代时都创建了一个自动释放池。因此,每次使用新的自动释放池运行以下行:
[[self.nsBackColor objectAtIndex:x] replaceObjectAtIndex:y withObject:color];
因此 color
将其在本地池中的引用计数增加一个,而 [[self.nsBackColor objectAtIndex:x] objectAtIndex:y]
将其在本地池中的引用计数减少一个本地池。但这里有一个问题:该项目在上一次迭代中是 color
,它的引用计数由您之前清空/释放的上一个池管理。
所以应该发生的事情是,当先前的池在先前的迭代中被释放时,该对象也被释放了。它的引用计数是 2(一个用于 [UIColor colorWith...]
,一个用于添加到数组),所以它应该在池被排空后立即收到 2 条释放消息,并且指针在 [[self.nsBackColor objectAtIndex:x] objectAtIndex:y]
中应该悬空,直到您在当前迭代中用指向 color
的指针替换它。
显然,这并没有完全按照预期的方式发生,也没有按照我的理解发生。但是,@autoreleasepool {}
指令显然放错了地方。它应该围绕 while (true)
循环,或者完全删除以支持线程池。
关于ios - NSMutableArray replaceObjectAtIndex :withObject Loop Leakage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15079177/
这是我的代码。 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRe
它们似乎执行相当相似的任务:启动一个新线程来快速轻松地执行该选择器。但有什么区别吗?也许与内存管理有关? 最佳答案 两者是相同的。 在 iOS 和 Mac OS X v10.5 及更高版本中,所有对象
通过使用 Xcode 5 并启用自动引用计数。 在基于非 NavigationController 的应用程序中,我使用了一个 UIButton,并且正确定义和连接了 IBAction 和 IBOut
我刚刚在 Three20 中看到一些代码,如下所示: SEL sel = @selector(textField:didAddCellAtIndex:); if ([self.delegate
所以我想做的是我有一个 NSMutableArray 数据需要传递给另一个 UITableViewController。这个 NSMutableArray 是一个 NSDictionaries 数组,
我想做performSelector:withObject:,但对象是CGFloat。所以它实际上不是一个对象。我怎样才能做到这一点? 我正在执行选择器的对象不是我的,我无法修改它。 例如 [xyz
我有一个按钮,如果密码正确,我想在触发 segue 之前使用密码实现。当您输入错误的密码时,一切看起来都很好,我已经实现了另一个alertView来告诉用户密码是错误的。 当警报 View 弹出并在延
如题。调用 performSelector:withObject:afterDelay 后需要调用 NSAutoReleasePool 吗? 我觉得performSelector:withObject
我有一个 View Controller ,它调用performSelector:withObject:afterDelay。但是,如果我在调用此方法后立即删除该 View Controller ,那
我正在尝试使用这段代码在 NSMutableArray 中分配对象 - (IBAction)variablePressed:(UIButton *)sender { NSString *variabl
我正在尝试使用这段代码在 NSMutableArray 中分配对象 - (IBAction)variablePressed:(UIButton *)sender { NSString *variabl
我有一个可变数组,最初我在使用范围时遇到了问题。我得到了一些关于如何解决这个问题的建议(这很有效),但现在数组不会替换给定索引处的对象。 这是代码: .h 文件: @interface myViewC
我已经设置了一个块以在不同的队列上运行,并在延迟后调用另一个方法: piemanQ = dispatch_queue_create(PIEMAN_QUEUE_NAME, NULL); dispatch
我不理解代码中的某些行为。我在 .m 文件的顶部定义了一个枚举: typedef NS_ENUM (NSInteger, connectionState) { tryingToConnect, con
我的 iOS 应用程序中有一个异步服务器请求: [self performSelectorInBackground:@selector(doSomething) withObject:nil]; 如何
我想在后台线程中运行一个方法,第一个方法将在几秒钟后在同一(后台)线程上运行另一个方法。我写了这个: - (IBAction)lauch:(id)sender { [self performS
这是一个已经在 SO 中回答的问题,但我无法在任何地方的 Apple 文档中找到它。你能给我指出正确的方向吗? 在以下主题中 Do I have to retain an object before
我在释放一个对象时遇到了 EXC_BAD_ACCESS,该对象具有很少的 performSelector:withObject:afterDelay,其中选择器方法正在调用另一个对象,而我正在释放该对
这个问题在这里已经有了答案: dispatch_after - GCD in Swift? (26 个回答) 关闭8年前。 我有一个 Objective-C 中的应用程序,我正在过渡到 Swift。在
我的问题是,在我的应用程序中的某个时刻,我调用 [performSelector: withObject: afterDelay:] 但在长达 1 秒的延迟期间,会发生一些事情来决定是否延迟方法应该或
我是一名优秀的程序员,十分优秀!