gpt4 book ai didi

cocoa-touch - 为什么实例方法中的弱成员可以在方法完成之前被清空?

转载 作者:行者123 更新时间:2023-12-03 17:39:14 28 4
gpt4 key购买 nike

为什么它在调试/发布/模拟器/设备组合之间会有所不同? (下面是示例代码。)

我继承了一些在模拟器和调试设备上“工作”的代码,但在发布设备上不工作(用于上一个 LLVM)。它与 ARC 和一个弱属性(应该很强)有关,但我不完全理解发生了什么,希望有人可以向我解释它以及为什么它在调试/发布/设备/模拟器之间有所不同。

我创建了一个简单的示例项目来演示这一点,其中包含 AppDelegate.m 中的所有代码,如下所示。在模拟器中运行时,记录的输出为:

-[BaseThingMaker baseMakeThing]: returning a Thing
-[ThingMaker makeThing]: returning a Thing
-[AppDelegate application:didFinishLaunchingWithOptions:]: got a Thing

在设备上运行时,记录的输出为:

-[BaseThingMaker baseMakeThing]: returning a Thing
-[ThingMaker makeThing]: returning a (null)
-[AppDelegate application:didFinishLaunchingWithOptions:]: got a (null)

在设备上(处于“调试”或“发布”状态),ThingMaker 中的弱 self.thing 为 null,即使对于方法完成之前的日志消息也是如此。在模拟器上,返回 self.thing 对象。

单窗口应用程序 (AppDelegate.m) 的示例代码:

#import "AppDelegate.h"

@interface Thing : NSObject
@end
@implementation Thing
@end

@interface BaseThingMaker : NSObject
-(Thing *)baseMakeThing;
@end

@implementation BaseThingMaker
-(Thing *)baseMakeThing
{
Thing *thing = [Thing new];
NSLog(@"%s: returning a %@", __PRETTY_FUNCTION__, NSStringFromClass([thing class]));
return thing;
}
@end


@interface ThingMaker : NSObject
- (id)makeThing;
@end

@interface ThingMaker ()
@property (weak, nonatomic) id thing;
@end

@implementation ThingMaker
- (id)makeThing
{
BaseThingMaker *baseThingMaker = [BaseThingMaker new];
self.thing = [baseThingMaker baseMakeThing];
NSLog(@"%s: returning a %@", __PRETTY_FUNCTION__, NSStringFromClass([self.thing class]));
return self.thing;
}
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
ThingMaker *thingMaker = [ThingMaker new];
id thingIWant = [thingMaker makeThing];
NSLog(@"%s: got a %@", __PRETTY_FUNCTION__, NSStringFromClass([thingIWant class]));
return YES;
}
@end

最佳答案

方法baseMakeThing不会返回其调用所拥有的对象,在本例中它返回一个自动释放的对象。如果它是一个自动释放对象,它将有一个所有者 - 自动释放池 - 直到运行循环循环时该池清空。因此,在发生这种情况之前,对弱属性的分配将一直有效,并且代码将看起来可以工作...

除非编译器进行优化,否则编译器有时会将对象从自动释放池中拉出并以这种方式获取所有权,而不是保留自动释放的对象。如果编译器这样做,那么在分配给弱属性后,编译器可以立即放弃所有权,因为稍后在 makeThing 中不会使用该引用,这又将使弱属性为空...

您看到的差异取决于编译器根据构建类型进行的优化程度。

关于cocoa-touch - 为什么实例方法中的弱成员可以在方法完成之前被清空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23960634/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com