小编duh*_*bel的帖子

为什么ARC的objc_autoreleaseReturnValue的实现对x86_64和ARM有所不同?

在阅读了Mike Ash的优秀博客文章"星期五Q&A 2014-05-09:当Autorelease不是"时,我决定查看ARC应用于加速保留/释放过程的优化的详细信息.我所指的技巧称为"快速自动释放",其中调用者和被调用者合作以将返回的对象保持在自动释放池之外.这在以下情况下效果最佳:

- (id) myMethod {
    id obj = [MYClass new];
    return [obj autorelease];
}

- (void) mainMethod {
   obj = [[self myMethod] retain];
   // Do something with obj
   [obj release];
}
Run Code Online (Sandbox Code Playgroud)

可以通过完全跳过自动释放池来优化:

- (id) myMethod {
    id obj = [MYClass new];
    return obj;
}

- (void) mainMethod {
   obj = [self myMethod];
   // Do something with obj
   [obj release];
}
Run Code Online (Sandbox Code Playgroud)

实现此优化的方式非常有趣.我引用Mike的帖子:

"在Objective-C运行时自动释放的实现中有一些非常奇特且令人费解的代码.在实际发送自动释放消息之前,它首先检查调用者的代码.如果它看到调用者将立即调用objc_retainAutoreleasedReturnValue,那么它完全是跳过消息发送.它实际上根本不进行自动释放.相反,它只是将对象存储在已知位置,这表示它根本没有发送自动释放."

到现在为止还挺好.NSObject.mm上的x86_64实现非常简单.代码分析位于返回地址之后的汇编程序,objc_autoreleaseReturnValue以便存在调用objc_retainAutoreleasedReturnValue.

static bool callerAcceptsFastAutorelease(const void * const ra0)
{
    const …
Run Code Online (Sandbox Code Playgroud)

assembly memory-management objective-c ios automatic-ref-counting

21
推荐指数
1
解决办法
1862
查看次数

使用依赖项分发(正确)iOS框架

让我们考虑以下场景:应用程序"MyApp"正在使用由Propretary MySDK.framework提供的SDK.反过来,MySDK依赖于开源库,如AFNetworking和RESTKit.为了分发MySDK,开发人员需要提供所有依赖项,例如,RESTKit需要AFNetworking 1.x并且它与2.0版不兼容.

在预框架场景中,MySDK使用的库都将嵌入到框架的二进制文件中,并且显然是一起发布的.如果MyApp需要使用AFNetworking或其他库,这些将嵌入应用程序的二进制文件中.在MyApp的和MySDK之间共享库的情况下,该代码将被复制并嵌入两个成MyApp的的二进制和MySDK的二进制.因此,如果MyApp需要AFNetworking 2.x,则不会发生冲突,因为每个二进制文件都会嵌入自己的版本.

输入框架.使用框架,每个库都被编译为单独的.framework,并在运行时链接到使用它的代码.为了分发具有所有依赖关系的MySDK,框架包在MySDK.framework/Frameworks目录中包含所有依赖关系作为"sub"-Frameworks.对于MyApp,MyApp将会在MyApp.app/Frameworks中包含MySDK框架以及特定于MyApp的swift库和所有其他依赖项.

如果将此类应用程序上传到iTunes connect,则服务器会拒绝它,原因如下:"验证错误:无效的捆绑包.[MySDK.framework path]中的包包含不允许的文件'Frameworks'".这似乎像iTunes只接受框架的第一级,然后一个直接嵌入到应用程序的包,但我无法找到任何地方的规则写的.

另一种方法是展平框架层次结构并将所有MySDK依赖项与MySDK.framework一起发布,让MyApp开发人员将它们包含在具有复制框架阶段的App包中.这会产生一个不同的问题:我们现在的情况是每个库只能有一个版本,所以如果MySDK需要AFNetworking 1.x,那么应用程序将无法使用AFNetworking 2.x,因为所有框架都在同样的水平,没有名称空间.为了解决这个问题,一种解决方案是为AFNetworking创建一个版本化框架并包含两个版本.不幸的是,这意味着我们每次出现时都需要为每个版本的库维护一个不同的包.Cocoapods不支持版本化框架,因此我们也会阻止MySDK用户使用它.即使在这种情况下,我们如何在编译时指定二进制文件应链接到哪个版本的框架?MySDK.framework是不是一个独立的单元了其稳定性取决于像导入正确的依赖关系到应用程序的外部行为.这听起来不太好.

有什么选择?我真的想在我们的代码上使用.frameworks/@ import,因为那是Apple的标题,但我觉得现在唯一的麻烦自由路径是使用现在过时且效率低下的静态库.

xcode frameworks itunesconnect ios

6
推荐指数
0
解决办法
321
查看次数