UIImage imageNamed引起的内存问题1

本文深入探讨了在iOS应用中使用UIImageimageNamed方法加载图片时可能导致的内存泄露问题。通过分析该方法的工作原理,指出其在大量图片加载场景下存在的隐患,并提出替代方案以确保应用内存管理的健康。

你还在使用myImage = [UIImage imageNamed:@"icon.png"];吗???!!!   

如题,是不是大家为了方便都这样加载图片啊
myImage = [UIImage imageNamed:@"icon.png"];
那么小心了
这种方法在一些图片很少,或者图片很小的程序里是ok的。
但是,在大量加载图片的程序里,请千万不要这样做。
为什么呢 ???????


这种方法在application bundle的顶层文件夹寻找由供应的名字的图象 。 如果找到图片,装载到iPhone系统缓存图象。那意味图片是(理论上)放在内存里作为cache的。

试想你图片多了,是什么后果``````
图片cache极有可能不会响应 memory warnings and release its objects

所以,用图片的时候一定要小心的alloc和release
推荐使用
NSString *path = [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"];
myImage = [UIImage imageWithContentsOfFile:path];

不过这种方法要注意了,如果有高清图,也就是@2x的,就不能自动获取到了,自己把握吧,做ui可以用imageNamed,要处理的大图就别这样加载了

[UIImage imageNamed:@""]使用误区

最近在做一个图像处理的app应用,应用中有很多图像资源。

为了方便,一开始读取图像资源的时候都是直接使用了[UIImage imageNamed:@""]方法,这个方法非常方便,一句话就可以从bundle中读取图片。

初步测试,功能一切正常。后来发现多次操作之后,应用经常发生内存警告从而导致自动退出的问题。定位之后发现是由于[UIImage imageNamed: @""]分配的图像都没有释放引起的。而之前从官方的reference中得到的信息应该是[UIImage imageNamed:@""]分配的图像系统会放到cache里面。而关于cache管理的规则就没有明确的介绍。由此看来[UIImage imageNamed:]只适合与UI界面中小的贴图的读取,而一些比较大的资源文件应该尽量避免使用这个接口。

最后通过直接读取文件路径[UIImage imageWithContentsOfFile]解决掉这个问题.


使用[UIImage imageWithContentOfFile:] 或者[image initWithContentOfFile:]
容易引起内存问题,UIImage imageNamed将为这个图像提供缓存,所以如果你再次需要同一图像时,图像将被从内部缓存而
不是从资源中加载。而坏消息也是iPhone将为此图像提供缓存。这样如果图片过多就好出现内存泄露的现象。
UIImage imageWithContentsOfFile将不提供缓存。

转载于:https://www.cnblogs.com/zsw-1993/archive/2012/10/12/4880808.html

/ // HBBaseTabbarViewController.m // wechat // // Created by josh on 2025/3/21. // #import "HBBaseTabbarViewController.h" #import "HBCustomTabBar.h" #import "HBFriendLineViewController.h" #import "HBProfileViewController.h" #import "HBHomeViewController.h" #import "HBContactViewController.h" @interface HBBaseTabbarViewController () @end @implementation HBBaseTabbarViewController - (void)viewDidLoad { [super viewDidLoad]; // 替换默认的 TabBar [self setValue:[[HBCustomTabbar alloc] init] forKey:@"tabBar"]; // 设置子视图控制器 [self setupViewControllers]; } - (void)setupViewControllers { // 创建 4 个子视图控制器 HBHomeViewController *homeVC = [[HBHomeViewController alloc] init]; // homeVC.view.backgroundColor = [UIColor whiteColor]; homeVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"首页" image:[UIImage imageNamed:@"home"] selectedImage:[UIImage imageNamed:@"home-sel"]]; HBContactViewController *contactVC = [[HBContactViewController alloc] init]; // contactVC.view.backgroundColor = [UIColor whiteColor]; contactVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"通讯录" image:[UIImage imageNamed:@"contact"] selectedImage:[UIImage imageNamed:@"tongxunlu-sel"]]; HBFriendLineViewController *frienVC = [[HBFriendLineViewController alloc] init]; frienVC.view.backgroundColor = [UIColor whiteColor]; frienVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"朋友圈" image:[UIImage imageNamed:@"pengyouquan"] selectedImage:[UIImage imageNamed:@"pengyouquan-sel"]]; HBProfileViewController *profileVC = [[HBProfileViewController alloc] init]; profileVC.view.backgroundColor = [UIColor whiteColor]; profileVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"我的" image:[UIImage imageNamed:@"me"] selectedImage:[UIImage imageNamed:@"me-sel"]]; // 将子视图控制器添加到 TabBarController self.viewControllers = @[homeVC, contactVC, frienVC, profileVC]; } 这一串代码的作用
最新发布
03-24
<think>好的,我现在要解析用户提供的Objective-C代码如何实现自定义TabBarController,特别是设置子视图控制器及其UITabBarItem的配置。首先,我需要回忆一下UITabBarController的基本结构和常用方法。 根据引用[1]和[2],UITabBarController通常通过设置代理来处理Tab项的选中事件,同时动态管理ViewController需要注意代理的弱引用问题。用户提到的代码可能涉及创建多个子视图控制器,并将它们添加到tabBarController的viewControllers数组中。 接下来,每个子控制器需要配置对应的UITabBarItem,包括标题、图标等属性。引用[1]中提到的tabBar:didSelectItem:方法可能在自定义选中效果时用到。另外,引用[3]指出TabBar在转场时可能存在不足,可能需要额外处理动画或布局。 然后,代码中可能包含设置代理的部分,如引用[2]所述,将tabBarController的delegate设为self,并确保遵守UITabBarDelegate协议。同时,动态添加或移除ViewController需要考虑引用计数和视图生命周期,这点在引用[1]的4.2.1提到过。 此外,引用[4]提到presentation结束后视图的恢复,这可能与自定义转场效果有关,但用户的问题主要集中在TabBar配置,这部分可能暂时不需要深入。 现在需要将这些点整合成步骤清晰的解析,包括创建子控制器、配置TabBarItem、设置代理等,并指出常见陷阱,如代理循环引用(需使用weak属性)。可能还需要代码示例来展示如何正确设置每个部分,比如viewControllers数组的赋值和TabBarItem的初始化。</think>### Objective-C实现自定义TabBarController代码解析 #### 1. 创建子视图控制器 需要为每个Tab项创建对应的视图控制器实例: ```objectivec UIViewController *vc1 = [[FirstViewController alloc] init]; UIViewController *vc2 = [[SecondViewController alloc] init]; UIViewController *vc3 = [[ThirdViewController alloc] init]; ``` #### 2. 配置UITabBarItem 每个视图控制器需要设置`tabBarItem`属性: ```objectivec vc1.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"首页" image:[UIImage imageNamed:@"home"] selectedImage:[UIImage imageNamed:@"home_selected"]]; vc2.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"消息" image:[UIImage imageNamed:@"message"] selectedImage:[UIImage imageNamed:@"message_selected"]]; vc3.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"我的" image:[UIImage imageNamed:@"profile"] selectedImage:[UIImage imageNamed:@"profile_selected"]]; ``` #### 3. 设置TabBarController 将子控制器数组赋值给`viewControllers`属性: ```objectivec self.viewControllers = @[vc1, vc2, vc3]; ``` #### 4. 设置代理(关键步骤) 在TabBarController实现类中: ```objectivec @interface CustomTabBarController () <UITabBarControllerDelegate> @end @implementation CustomTabBarController - (void)viewDidLoad { [super viewDidLoad]; self.delegate = self; // 必须遵守协议并设置代理 } ``` 注意要使用弱引用避免循环引用,如引用[2]所述:"注意delegate属性的弱引用问题" #### 5. 处理选中事件 实现`tabBarController:didSelectViewController:`代理方法: ```objectivec - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { // 在此处添加选中Tab后的处理逻辑 NSLog(@"切换到%@控制器", viewController.title); } ``` ### 关键配置说明 | 配置项 | 作用说明 | 相关引用 | |----------------------|--------------------------------------------------------------------------|------------------| | viewControllers | 存储所有子控制器的数组,决定Tab栏显示项 | 基础配置 | | tabBarItem | 控制Tab项的图标/标题/角标等视觉元素 | 引用[1]的协议实现 | | delegate属性 | 实现Tab切换事件监听和自定义转场控制 | 引用[2][3] | | selectedIndex | 通过编程方式切换当前选中Tab(如引用[2]所述`tabBarVC.selectedIndex=...`) | 动态控制 | ### 典型陷阱 1. **代理循环引用**:忘记将delegate声明为weak属性会导致内存泄漏 2. **图片尺寸不规范**:未准备@2x/@3x多尺寸图片导致图标模糊 3. **视图生命周期冲突**:动态添加/移除控制器时未正确处理viewWillAppear等生命周期方法(如引用[1]4.2.1所述)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值