@autoreleasepool 导致堆栈损坏(ARC,使用 llvm 3.0 编译,最快,最小 [-Os])

发布于 2024-12-11 06:19:19 字数 2844 浏览 0 评论 0原文

一个加载图像并记录其大小的小程序。它是用 ARC 支持 llvm 3.0 编译的。我在 iPod 4.2 上运行它并得到一些有趣的数字...该程序是用“-Os”在“Release”模式下编译的(xcode 中“Release”的默认优化)。这整件事不会发生在模拟器中。在我看来,@autoreleasepool 与循环相结合会损坏堆栈...请注意,我必须通过这个简单的示例来隔离这篇文章的问题。

--------->

int main(int argc, char *argv[])
{        
    @autoreleasepool
    {
        return UIApplicationMain(argc, argv, nil,
                                 @"AppDelegate");
    }    
}

@interface AppDelegate : UIWindow <UIApplicationDelegate>
@end

@implementation AppDelegate

-(void)loadImageAndLogValues
{
        // image from bundle 256x26
    UIImage *image = [UIImage imageNamed:@"Image.png"];

    for (int i = 0; i < 1; i++)
    {
      NSLog(@"size=%@", NSStringFromCGSize(image.size));
      NSLog(@"w=%f", image.size.width);
      NSLog(@"h=%f", image.size.height);
      NSLog(@"------------------------");
    }
}

-(BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    self.frame = [UIScreen mainScreen].bounds;
    self.backgroundColor = [UIColor blueColor];
    [self makeKeyAndVisible];

    [self loadImageAndLogValues];

    UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
        initWithTarget:self 
                action:@selector(loadImageAndLogValues)];
    [self addGestureRecognizer:tap];

    return YES;
}

@end

<------------------

这是我点击屏幕一次后的输出(点击后记录时“h”是错误的!图像的高度是 26...):

2011-10-21 01:54:48.677 Tmp[2522:307] size={256, 26}
2011-10-21 01:54:48.696 Tmp[2522:307] w=256.000000
2011-10-21 01:54:48.705 Tmp[2522:307] h=26.000000
2011-10-21 01:54:48.715 Tmp[2522:307] ------------------------
2011-10-21 01:54:50.576 Tmp[2522:307] size={256, 26}
2011-10-21 01:54:50.582 Tmp[2522:307] w=256.000000
2011-10-21 01:54:50.589 Tmp[2522:307] h=256.000000
2011-10-21 01:54:50.595 Tmp[2522:307] ------------------------

现在,我从 main() 中删除 @autoreleasepool:

int main(int argc, char *argv[])
{        
        //@autoreleasepool
        //{
        return UIApplicationMain(argc, argv, nil,
                                 @"AppDelegate");
        //}    
}

运行程序并点击。 “h”的值仍然错误,但是当直接从“application:didFinishLaunchingWithOptions:”调用“loadImageAndLogValues”时...

2011-10-21 02:02:08.222 Tmp[2544:307] size={256, 26}
2011-10-21 02:02:08.240 Tmp[2544:307] w=256.000000
2011-10-21 02:02:08.250 Tmp[2544:307] h=256.000000
2011-10-21 02:02:08.259 Tmp[2544:307] ------------------------
2011-10-21 02:04:59.097 Tmp[2544:307] size={256, 26}
2011-10-21 02:04:59.103 Tmp[2544:307] w=256.000000
2011-10-21 02:04:59.109 Tmp[2544:307] h=26.000000
2011-10-21 02:04:59.115 Tmp[2544:307] ------------------------

那么?...ARC + llvm 3.0 + -Os + @autoreleasepool + for(;;) + image.size .width/height 对我不起作用:) 请帮忙!谢谢你!

A small program which loads image and logs its size. It is compiled with ARC support, llvm 3.0. I run it on iPod 4.2 and get some funny numbers... The program is compiled in "Release" mode with "-Os" (default optimization for "Release" in xcode). This whole thing does NOT happen in Simulator. It looks to me that @autoreleasepool in combination with a loop corrupts stack... Note, that I had to isolate the problem for this post with this simple example.

--------->

int main(int argc, char *argv[])
{        
    @autoreleasepool
    {
        return UIApplicationMain(argc, argv, nil,
                                 @"AppDelegate");
    }    
}

@interface AppDelegate : UIWindow <UIApplicationDelegate>
@end

@implementation AppDelegate

-(void)loadImageAndLogValues
{
        // image from bundle 256x26
    UIImage *image = [UIImage imageNamed:@"Image.png"];

    for (int i = 0; i < 1; i++)
    {
      NSLog(@"size=%@", NSStringFromCGSize(image.size));
      NSLog(@"w=%f", image.size.width);
      NSLog(@"h=%f", image.size.height);
      NSLog(@"------------------------");
    }
}

-(BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    self.frame = [UIScreen mainScreen].bounds;
    self.backgroundColor = [UIColor blueColor];
    [self makeKeyAndVisible];

    [self loadImageAndLogValues];

    UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
        initWithTarget:self 
                action:@selector(loadImageAndLogValues)];
    [self addGestureRecognizer:tap];

    return YES;
}

@end

<------------------

And this is the output after I tap the screen once ("h" is WRONG when logged after tapping! The height of the image is 26...):

2011-10-21 01:54:48.677 Tmp[2522:307] size={256, 26}
2011-10-21 01:54:48.696 Tmp[2522:307] w=256.000000
2011-10-21 01:54:48.705 Tmp[2522:307] h=26.000000
2011-10-21 01:54:48.715 Tmp[2522:307] ------------------------
2011-10-21 01:54:50.576 Tmp[2522:307] size={256, 26}
2011-10-21 01:54:50.582 Tmp[2522:307] w=256.000000
2011-10-21 01:54:50.589 Tmp[2522:307] h=256.000000
2011-10-21 01:54:50.595 Tmp[2522:307] ------------------------

Now, I remove @autoreleasepool from main():

int main(int argc, char *argv[])
{        
        //@autoreleasepool
        //{
        return UIApplicationMain(argc, argv, nil,
                                 @"AppDelegate");
        //}    
}

Run the program and tap. Still wrong value for "h", but when calling "loadImageAndLogValues" directly from "application:didFinishLaunchingWithOptions:"...

2011-10-21 02:02:08.222 Tmp[2544:307] size={256, 26}
2011-10-21 02:02:08.240 Tmp[2544:307] w=256.000000
2011-10-21 02:02:08.250 Tmp[2544:307] h=256.000000
2011-10-21 02:02:08.259 Tmp[2544:307] ------------------------
2011-10-21 02:04:59.097 Tmp[2544:307] size={256, 26}
2011-10-21 02:04:59.103 Tmp[2544:307] w=256.000000
2011-10-21 02:04:59.109 Tmp[2544:307] h=26.000000
2011-10-21 02:04:59.115 Tmp[2544:307] ------------------------

So?... ARC + llvm 3.0 + -Os + @autoreleasepool + for(;;) + image.size.width/height is not working for me :) Please help! Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢望 2024-12-18 06:19:19

(顺便说一句)阅读LLVM vs. GCC for iOSdevelopment后成功解决了这个问题...ARMv6正是适合我的iPod这带来了麻烦。 “修复”是仅禁用对 ARMv6 配置的拇指支持。很棒,但很奇怪...

在此处输入图像描述

After (incidentally) reading LLVM vs. GCC for iOS development managed to fix the problem... ARMv6 is exactly for my iPod which was giving troubles. The "fix" is to disable thumb support for ARMv6 configuration only. Great, but weird...

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文