Objective-C静态库中含有category怎么办?

1、苹果推荐的方法

找到 target,更改其 Other Linker Flags 为: -all_load 或 -force_load

-force_load,后跟随一个文件位置,可以更精确地加载所需文件。 简单点说就是,Objective-C 的动态特性使得需要,为链接器添加一个标签(设置 Other Linker Flags 为 -ObjC)来解决通过 Category

向类添加方法的问题。 但这个标签 -ObjC 在 64 位 和 iOS 中有问题,需要使用 -all_load 或 -force_load。

缺点:会将所有的符号都导入进来,造成库比较大。

2、我的方法

在category声明的地方添加一个类,然后随便实现一个方法,然后在target中调用这个category中类的方法。但是如果有很多category的话一个一个添加比较麻烦,所以呢,我直接定义了几个宏来简化操作。

宏定义如下:

//
//  FixCategoryBug.h
//  MainLib
//
//  Created by shaozg on 15/7/31.
//  Copyright (c) 2015年 shaozg. All rights reserved.
//

#ifndef MainLib_FixCategoryBug_h
#define MainLib_FixCategoryBug_h

#define __kw_to_string_1(x) #x
#define __kw_to_string(x)  __kw_to_string_1(x)

// 需要在有category的头文件中调用,例如 KW_FIX_CATEGORY_BUG_H(NSString_Extented)
#define KW_FIX_CATEGORY_BUG_H(name) \
    @interface KW_FIX_CATEGORY_BUG_##name : NSObject \
        +(void)print;     @end 

// 需要在有category的源文件中调用,例如 KW_FIX_CATEGORY_BUG_M(NSString_Extented)
#define KW_FIX_CATEGORY_BUG_M(name) \
    @implementation KW_FIX_CATEGORY_BUG_##name \
        + (void)print {             NSLog(@"[Enable category %s]", __kw_to_string(name));         }     @end 

// 在target中启用这个宏,其实就是调用下category中定义的类的print方法。
#define KW_ENABLE_CATEGORY(name) [KW_FIX_CATEGORY_BUG_##name print]

#endif

NSString+Extented.h如下:

//
//  NSString+Extented.h
//  MainLib
//
//  Created by shaozg on 15/7/31.
//  Copyright (c) 2015年 shaozg. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "FixCategoryBug.h"

KW_FIX_CATEGORY_BUG_H(NSString_Extented)

@interface NSString (Extented)

- (NSString *)testCategory;

@end

NSString+Extented.m内如如下:

//
//  NSString+Extented.m
//  MainLib
//
//  Created by shaozg on 15/7/31.
//  Copyright (c) 2015年 shaozg. All rights reserved.
//

#import "NSString+Extented.h"

KW_FIX_CATEGORY_BUG_M(NSString_Extented)

@implementation NSString (Extented)

- (NSString *)testCategory {
    return self;
}
@end

需要调用category的其它target部分代码如下:

#import "AppDelegate.h"
#import "MainLib.h"
#import "NSString+Extented.h"
#import "SubLib.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
//    ENABLE_CATEGORY(NSString);
    KW_ENABLE_CATEGORY(NSString_Extented);

    NSLog(@"不会出错了吧? %@", [@"当然!" testCategory]);
    return YES;
}

优点:使用简单,根本不用改编译选项;也不会增加库的体积。

缺点:没有缺点

如果小伙伴们有更简单的方法,请一定分享吧!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-23 23:26:07

Objective-C静态库中含有category怎么办?的相关文章

如何让静态库中的可执行程序不调用的函数不链接进该可执行程序?(-ffunction-sections -Wl,--gc-sections)

如何让静态库中的可执行程序不调用的函数不链接进该可执行程序?(-ffunction-sections -Wl,--gc-sections) 关键词: -Wl,--gc-sections   -ffunction-sections  链接  elf   库 有时我们会遇到这种情况,可执行程序需要链接一些静态库,但是静态库中的函数并没有全部使用,只用了其中的几个,但是系统默认会自动把整个静态库全部链接到可执行程序中,造成可执行程序的大小大大增加,浪费了flash空间和内存空间.gcc为我们提供的解决

在共享DLL中使用MFC 和在静态库中使用MFC的区别

使用VS2008,在项目属性中有一项MFC的使用,有三种设置: 1.使用标准Windows库 2.在共享DLL中使用MFC 3.在静态库中使用MFC 第一种顾名思义. 第二种指的是打包时一些MFC的DLL的内容没有被包含在EXE文件中,所以EXE文件较小,但是运行时要求系统中要有相关的DLL文件. 第三种是将DLL中的相关代码写进EXE文件中,文件较大,但是可以在没有相关DLL的机器上运行. 同时,如果程序本来是第二种方式,发给同事,在同事机器上运行时,可能会出现错误: “无法启动程序……,由于

plist文件无法打包进.a静态库中

问题: 之前一直在做静态库的编写与维护,也一直知道静态库的图片资源是没办法打进.a中的.可是突然有个想法.由于有非常多參数的配置是在一个plist文件里的.尽管也知道这是一个plist文件,可是想想和图片资源还是有一定差别的.所以就尝试着是否能把plist打进静态库中. 分析: 1. 创建了一个简单的生成静态库的功能,然后公开了一个接口.用来输出读取plist文件的结果. 2. 创建一个简单的project,来使用上一步生成的.a文件,然后调用那个公开的接口. 3. 结果是无法读取,输出为nul

使用“在静态库中使用 MFC”的静态库

开发工具:visual studio 2013 pro 一共是两个项目,一个是A:项目名称MySdk,静态库,多字节,在静态库中使用 MFC,运行库使用“多线程调试 DLL (/MDd)”:另一个是B:可执行程序,多字节,在静态库中使用 MFC,预处理器定义增加_AFXDLL,运行库使用“多线程调试 DLL (/MDd)”. 项目A的接口文件中: #ifdef MYSDKINTERFACE_STATIC #define MYSDKINTERFACE_API #else #ifdef MYSDKI

iOS framework静态库中使用xib和图片资源详解

一.新建bundle 前2篇文章介绍了iOS 最新framework和.a静态库制作及使用全解   iOS 工程套子工程,主工程和framework工程或.a library静态库工程联调 我现在是在主工程的子工程里进行,当然你在创建静态库工程(子工程)的时候也可以.前面我是懒得再建工程了,接着现成主工程套子工程的项目. 1.按下图步骤操作 2.因为iOS框架中没有bundle,要选中OS X框架找到bundle,如下图 二.往bundle加资源文件 将工程中的资源文件都加入到刚刚建的bundl

如何使用C/C++动态库与静态库中的宏

在哪个cpp文件中使用的该动态库或静态库,就在该h/cpp文件所在的工程的预处理命令中添加库中的宏. 如有库工程add,其头文件如下 #ifndef _ADD_H #define _ADD_H #if defined( _WIN32 ) || defined( __MINGW32__ ) # if defined( ADD_EXPORTS ) # define ADD_EXPORT __declspec(dllexport) # elif defined( ADD_USE_DLL_IMPORT

Linux的nm命令查看动态库和静态库中的符号

功能 列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等.所谓符号,通常指定义出的函数,全局变量等等. 使用 nm [option(s)] [file(s)] 有用的options: -A 在每个符号信息的前面打印所在对象文件名称: -C 输出demangle过了的符号名称: -D 打印动态符号: -l 使用对象文件中的调试信息打印出所在源文件及行号: -n 按照地址/符号值来排序: -u 打印出那些未定义的符号: 常见的符号类型: A 该符号的值在今后的链接中将不再改变

iOS 最新framework和.a静态库制作及使用全解

最近想把自己的一些实用工具类搞成一个静态库,网上搜了下关于framework和.a的一些相关资料,然而写的或不全面,或不详细,我归纳总结及亲自实践写下这篇文章. 一.framework和.a两种静态库的介绍及区别 .a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件. .a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用. .a + .h + sourceFile = .framework. .a只是静态库.framework既可以是静态库也

Xcode中导入.a静态库后报错添加-force_load或-all_load

第一种方法: 以前在做项目的时候在Xcode中倒入一个三方SDK的时候,会有一些.a的静态库,这时候如果直接编译运行就会报错.当时只知道往build settings的linker flags 里面添加-force_load和.a文件的路径.最近又多次用到,这里总结一下. 例如在Xcode中倒入一个SIPSKDK,如下,这里面包含了一个.a的静态库. 如果直接运行的没用到里面方法的时候运行时没问题的,但是一旦导入头文件,并创建SIPClient对象的时候就会报错,如下所示: 这里报错的原因主要是