zoukankan      html  css  js  c++  java
  • 浅谈NSBundle

           图片、xib等资源文件无法直接封入静态库,要想在静态库中使用他们,就必须借助于bundle

           那么什么是bundle呢?

           简单来说,bundle就是一个内部结构按照标准规则组织的特殊目录,即directory

     

           要知道,iOS的应用都是通过bundle进行封装的,对应的bundle类型是Application类型,平时我们通过XCode编译出来的Target(即我们开发的应用),其实就是一个Application类型bundle,即一个文件夹!但是Finder会把这个bundle当做一个文件显示给我们,因为这个bundle自身也是一个package,而Mac系统会把所有的package当做一个文件来对待,显示给用户,从而防止用户误操作导致程序文件损坏或丢失。在Finder中,一个应用程序看上去和其他文件没有什么区别. 但是实际上它是一个包含了nib文件,编译代码,以及其他资源的目录,我们把这个目录叫做程序的main bundle。


           其实bundle对iOS开发者来讲,最大的方便就是可以非常简单地让自己的应用国际化,在不同的语言,不同的地区,加载不同的资源文件,显示不同的语言文字,实现这些只需要我们严格按照bundle的要求进行资源文件的存放,而不需要写大量代码判断地区语言。遵循的方法也很简单:创建对应的"本地化文件夹"。例如我们要同时让图片"pic.png"在中文和英文下显示不同的内容,只需要创建两个本地化文件夹zh.lproj和en.lproj,然后分别放入同名但内容不同的"pic.png"。

     

           由此可知,在国际化过程中,应用可以从bundle中读取图片、多媒体及nib界面等资源文件,那么静态库和framework也同样可以利用bundle这个特性,将其需要的资源文件存入bundle中,至于国际化过程中,为什么需要不同的nib文件,这一点也不难理解,对于同一个界面,中文和英文界面的布局有可能不会完全相同,这就需要创建多个同名的nib文件,将其放入bundle中对应的目录下。

     

    bundle的使用:

           bundle是静态的,也就是说,我们包含到包中的资源文件作为一个资源包是不参加项目编译的。也就意味着,bundle包中不能包含可执行的文件。它仅仅是作为资源,被解析成为特定的二进制数据。

           由于是静态的,bundle使用也变得非常简单:将要使用的bundle集成到项目中,要使用bundle中的资源,只需要找到相应的资源路径,一句话:bundle玩的只是路径。

     

        //首先找到我们的bundle文件
        NSBundle *myBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource: @"MyBundle" ofType :@"bundle"]];
        
        //获取bundle中的nib资源
        ViewController1 *viewCtl1 = [[ViewController1 alloc] initWithNibName: @"ViewController1" bundle: myBundle];
        
        //获取bundle中的图片资源
        UIImage *image = [UIImage imageWithContentsOfFile: [[myBundle resourcePath]
                                                            stringByAppendingPathComponent: @"0003.jpg"]]; //绝对路径法
        
        //或者
        UIImage *image = [UIImage imageWithContentsOfFile: [myBundle pathForResource: @"0003" ofType: @"jpg"]];   //相对路径法
        
        //甚至可以...
        UIImage *image1 = [UIImage imageNamed:@"MyBundle.bundle/0003.jpg"];  //纯路径法
        //imageNamed方法是从mainBundle中获取资源,而此处Mybundle.bundle可以被认为是存在与mainBundle中的一个目录,这样理解该用法就比较容易了
        
        //获取子目录中所有类型为"JPG"的文件
        NSArray *arr = [myBundle pathsForResourcesOfType: @"JPG" inDirectory: nil];
        
        //当然,可以写成预编译语句:
        
        #define MYBUNDLE_NAME @ "MyBundle.bundle"
        #define MYBUNDLE_PATH [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: MYBUNDLE_NAME]
        #define MYBUNDLE [NSBundle bundleWithPath: MYBUNDLE_PATH]

    或者方法

    #import <Foundation/Foundation.h>
    
    #define BUNDLE_NAME @"MyToolsWithAssetsA"
    
    @interface BundleTools : NSObject
    
    + (NSString *)getBundlePath: (NSString *) assetName;
    + (NSBundle *)getBundle;
    
    @end
    
    #import "BundleTools.h"
    
    @implementation BundleTools
    
    + (NSBundle *)getBundle{
        
        return [NSBundle bundleWithPath: [[NSBundle mainBundle] pathForResource: BUNDLE_NAME ofType: @"bundle"]];
    }
    
    + (NSString *)getBundlePath: (NSString *) assetName{
        
        NSBundle *myBundle = [BundleTools getBundle];
        
        if (myBundle && assetName) {
            
            return [[myBundle resourcePath] stringByAppendingPathComponent: assetName];
        }
        
        return nil;
    }
    
    @end
    

      

    有一点需要注意:

    既然有绝对路径法可以获取bundle中的资源,为什么还要有相对路径法呢?

           正如我们前面所讲,bundle对iOS开发者来讲,最大的方便就是可以非常简单地让自己的应用国际化,在不同的语言不同的地区,加载不同的资源文件,显示不同的语言文字,而实现这些只需要我们严格按照bundle的要求进行资源文件的存放即可,不需要写大量代码判断地区语言。如果我们使用文件系统的绝对路径法,当需要App国际化的时候,就只能自己去实现不同语言、不同地区的情况下加载对应的文件,如果有部分资源文件公用,部分需要国际化,那么此时,对开发人员来讲,代码维护起来将会是一场灾难。所以,我们要尽量去选用相对路径法加载资源。

     

  • 相关阅读:
    分页
    ARC127C Binary Strings 思维 二进制 树
    ARC127A Leading 1s 数位DP
    【算法复习】背包问题 经典动态规划
    iOS15真机调试包下载
    Linux基础03 绝对路径/相对路径, 切换目录cd, 创建目录mkdir, 创建文件touch, 树状显示tree, 复制cp
    Jedis支持哨兵模式下认证
    19C ORA-00600: internal error code, arguments: [kkmmctbf:bad intcoln], [49]
    useMemo 和 useCallback 简单理解
    前端大屏页面布局经验
  • 原文地址:https://www.cnblogs.com/mylizh/p/3971757.html
Copyright © 2011-2022 走看看