loadView

一、loadView

1.什么时候被调用?

每次访问UIViewController的view(比如controller.view、self.view)而且view为nil,loadView方法就会被调用。

2.有什么作用?

loadView方法是用来负责创建UIViewController的view

3.默认实现是怎样的?

默认实现即[super loadView]里面做了什么事情。

1> 它会先去查找与UIViewController相关联的xib文件,通过加载xib文件来创建UIViewController的view

  • 如果在初始化UIViewController指定了xib文件名,就会根据传入的xib文件名加载对应的xib文
[[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil];
  • 如果没有明显地传xib文件名,就会加载跟UIViewController同名的xib文件
[[MJViewController alloc] init]; // 加载MJViewController.xib

2> 如果没有找到相关联的xib文件,就会创建一个空白的UIView,然后赋值给UIViewController的view属性,大致如下

self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
// applicationFrame的值是:{{x = 0, y = 20}, {width = 320, height = 460}}

[super loadView]里面就大致完成1>和2>中叙述的内容

4.怎样正确使用这个方法?

大家都知道UIViewController的view可以通过xib文件来创建,但是在某些情况下,xib不是那么地灵活,所以有时候我们想通过代码来创建UIView,比如:

self.view = [[[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];

 如果想通过代码来创建UIViewController的view,就要重写loadView方法,并且不需要调用[super loadView],因为在第3点里面已经提到:若没有xib文件,[super loadView]默认会创建一个空白的UIView。我们既然要通过代码来自定义UIView,那么就没必要事先创建一个空白的UIView,以节省不必要的开销。正确的做法应该是这样:

1 - (void)loadView {
2     self.view = [[[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
3 }

不需要调用[super loadView],你调用了也不会出错,只是造成了一些不必要的开销。

总结一句话,苹果设计这个方法就是给我们自定义UIViewController的view用

 

二、viewDidLoad

1.什么时候被调用?

无论你是通过xib文件还是重写loadView方法创建UIViewController的view,在view创建完毕后,最终都会调用viewDidLoad方法

2.有什么作用?

一般我们会在这里做界面上的初始化操作,比如往view中添加一些子视图、从数据库或者网络加载模型数据装配到子视图中。例如:

复制代码
1 - (void)viewDidLoad
2 {
3     [super viewDidLoad];
4     
5     // 添加一个按钮
6     UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
7     [button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
8     [self.view addSubview:button];
9 }
复制代码

 

三、viewDidUnload

1.什么时候被调用?

iOS设备的内存是极其有限的,如果应用程序占用的内存过多的话,系统就会对应用程序发出内存警告。UIViewController就会收到didReceiveMemoryWarning消息。didReceiveMemoryWarning方法的默认实现是:如果当前UIViewController的view不在应用程序的视图层次结构(View Hierarchy)中,即view的superview为nil的时候,就会将view释放,并且调用viewDidUnload方法

2.有什么作用?

上面说到,发出内存警告且view被释放的时候就会调用viewDidUnload方法,所以一般在释放资源,主要是释放界面元素相关的资源,将相关的实例都赋值为nil

1 - (void)viewDidUnload {
2     [super viewDidUnload];
3     self.name = nil;
4     self.pwd = nil;
5 }

3.dealloc也是用来释放资源的,那跟viewDidUnload有什么关系?

当发出内存警告调用viewDidUnload方法时,只是释放了view,并没有释放UIViewController,所以并不会调用dealloc方法。即viewDidUnload和dealloc方法并没有任何关系,dealloc方法只会在UIViewController被释放的时候调用

 

四、三个方法的关系

1.第一次访问UIViewController的view时,view为nil,然后就会调用loadView方法创建view

2.view创建完毕后会调用viewDidLoad方法进行界面元素的初始化

3.当内存警告时,系统可能会释放UIViewController的view,将view赋值为nil,并且调用viewDidUnload方法

4.当再次访问UIViewController的view时,view已经在3中被赋值为nil,所以又会调用loadView方法重新创建view

5.view被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化

<think>好的,我需要分析用户提供的这个JavaScript函数generaRoutes,并解释它的作用。首先,我会通读代码,理解每个部分的功能。 首先,函数接收三个参数:routes、data和parentPath,默认值为空字符串。看起来这个函数是用来生成路由配置的,可能是在一个前端框架(比如Vue Router)中动态生成路由结构。 接下来,函数遍历data数组中的每个item。当item的isAccredit为true时,进行进一步处理。这里有一个条件判断,检查item的category是否为"moudle"或"menu",转换为小写后比较。这里可能存在拼写错误,应该是"module"而不是"moudle"?不过代码中是这么写的,可能是用户代码中的实际名称。 然后,构建fullPath,如果parentPath存在,则拼接父路径和当前item的path,否则直接使用item.path。接下来创建一个menu对象,其结构看起来像Vue Router的路由配置对象。对于category是"moudle"的情况,path前面加上斜杠,而component根据category决定是使用Layout组件还是动态加载的组件(通过loadView函数)。同时设置hidden为false,children数组,以及meta信息包含图标和标题。 如果当前item有children属性,递归调用generaRoutes处理子项,将menu.children作为新的routes传入,并传递当前的fullPath作为父路径。最后,将生成的menu推入routes数组,最终返回routes。 可能的疑问点:category的拼写是否正确?loadView函数的作用是什么?Layout是否指布局组件?此外,处理路径时,是否要考虑路径拼接的正确性,比如避免双斜杠? 需要确认这些部分是否在代码中有特殊处理,或者是否存在潜在的错误。例如,当parentPath为空时,fullPath是item.path,但如果item是"moudle",path前面加斜杠,可能会导致路径如"/users"加上子路径变成"/users/profile",而如果是"menu"则可能是"users/profile",取决于具体逻辑。 另外,递归处理子项时,menu.children作为routes参数传递,这样每个子项会被添加到父级的children数组中,形成嵌套路由结构。 总结来说,这个函数的作用是根据传入的data数组,生成符合Vue Router格式的路由配置,支持嵌套路由,并根据category类型决定组件和路径处理方式。</think>这个 `generaRoutes` 函数是一个递归生成路由配置的JavaScript工具函数,主要用于动态构建前端路由树结构。下面分步骤解释其工作原理: --- ### 一、**函数参数** ```javascript function generaRoutes(routes, data, parentPath = "") ``` - `routes`: 目标路由数组(会被修改) - `data`: 原始路由配置数据源 - `parentPath`: 父级路径(用于递归拼接完整路径) --- ### 二、**核心逻辑解析** #### 1. **遍历数据源** ```javascript data.forEach((item) => { if (item.isAccredit == true) { // 权限校验 // 只处理 category 为 "moudle" 或 "menu" 的项(注意拼写问题,应为 module) if (item.category.toLowerCase() == "moudle" || item.category.toLowerCase() == "menu") { ``` - **权限过滤**: 仅处理 `isAccredit` 为 `true` 的项 - **分类过滤**: 只处理分类为 `moudle`(疑似拼写错误,应为 `module`)或 `menu` 的项 --- #### 2. **路径拼接** ```javascript const fullPath = parentPath ? `${parentPath}/${item.path}` : item.path; ``` - **完整路径**: 递归拼接父路径与当前项路径,例如: - 父路径为 `/admin`,当前路径为 `users` → 生成 `/admin/users` --- #### 3. **路由对象构造** ```javascript const menu = { path: item.category.toLowerCase() == "moudle" ? "/" + item.path : item.path, name: item.path, component: item.category.toLowerCase() == "moudle" ? Layout : loadView(`${fullPath}/index`), hidden: false, children: [], meta: { icon: item.icon, title: item.name } }; ``` - **path 规则**: - 若分类为 `moudle` → 路径前加斜杠(如 `/dashboard`) - 若分类为 `menu` → 直接使用路径(如 `overview`) - **component 加载**: - `moudle` 使用 `Layout` 布局组件 - `menu` 动态加载组件(如 `loadView('dashboard/overview/index')`) - **meta 信息**: 存储图标和标题供侧边栏等UI使用 --- #### 4. **递归处理子路由** ```javascript if (item.children) { generaRoutes(menu.children, item.children, fullPath); } ``` - 如果当前项有子路由,递归生成子路由配置 - 子路由会被添加到 `menu.children` 数组中 --- #### 5. **结果收集** ```javascript routes.push(menu); ``` - 将生成的路由对象推入目标数组 `routes` --- ### 三、**典型使用场景** 假设输入数据如下: ```javascript const data = [{ isAccredit: true, category: "Moudle", path: "dashboard", icon: "chart", name: "控制台", children: [{ isAccredit: true, category: "Menu", path: "overview", icon: "pie-chart", name: "概览" }] }]; ``` 输出路由结构: ```javascript [ { path: "/dashboard", name: "dashboard", component: Layout, hidden: false, children: [{ path: "overview", name: "overview", component: loadView("dashboard/overview/index"), meta: { icon: "pie-chart", title: "概览" } }], meta: { icon: "chart", title: "控制台" } } ] ``` --- ### 四、**潜在问题** 1. **拼写错误**: `moudle` 应为 `module` 2. **路径规范**: 未处理路径中的重复斜杠(如 `parentPath` 以斜杠结尾时) 3. **性能问题**: 频繁调用 `loadView` 可能导致动态导入过多 --- ### 五、**优化建议** ```javascript // 路径标准化处理 const normalizedParent = parentPath.endsWith('/') ? parentPath.slice(0, -1) : parentPath; const fullPath = normalizedParent ? `${normalizedParent}/${item.path}` : item.path; ``` 这个函数常见于Vue/React路由权限管理场景,通过后端数据动态生成前端路由结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值