ios – 弱房产的开销很大?

ios – 弱房产的开销很大?,第1张

概述在大约100,000次setDelegate调用之后,我的iOS应用程序在setDelegate上停顿了大约15秒. 将委托属性从弱更改为分配可以解决问题.知道为什么弱的财产有这么多的开销并拖延应用程序? 我怀疑弱引用是在数组中维护的,因此运行时可以通过它们循环,并在委托对象被释放时将指针设置为nil.阵列是否有最大尺寸?当n接近100,000时,失速变得更长. 示例代码如下: 头文件: #imp 在大约100,000次setDelegate调用之后,我的iOS应用程序在setDelegate上停顿了大约15秒.
将委托属性从弱更改为分配可以解决问题.知道为什么弱的财产有这么多的开销并拖延应用程序?

我怀疑弱引用是在数组中维护的,因此运行时可以通过它们循环,并在委托对象被释放时将指针设置为nil.阵列是否有最大尺寸?当n接近100,000时,失速变得更长.

示例代码如下:

头文件:

#import <Foundation/Foundation.h>@protocol GraphDataPointDelegate <NSObject>- (BOol)drawGraphBydistance;@end@interface GraphDataPoint : NSObject- (ID)initWithYValue:(NSNumber *)yValue withTime:(NSNumber *)time withdistance:(NSNumber *)distance withDelegate:(ID <GraphDataPointDelegate> )delegate;@end@interface Graph : NSObject <GraphDataPointDelegate>@end

M文件

#import "Graph.h"@interface GraphDataPoint ()@property (nonatomic,weak,reaDWrite) ID <GraphDataPointDelegate> delegate;@property (nonatomic,strong,reaDWrite) NSNumber *yValue;@property (nonatomic,reaDWrite) NSNumber *time;@property (nonatomic,reaDWrite) NSNumber *distance;@end@implementation GraphDataPoint- (ID)initWithYValue:(NSNumber *)yValue withTime:(NSNumber *)time withdistance:(NSNumber *)distance withDelegate:(ID<GraphDataPointDelegate>)delegate {    self = [super init];    if (self) {        self.yValue = yValue;        self.time = time;        self.distance = distance;        self.delegate = delegate;    }    return self;}- (ID)graphXValue {    if ([_delegate drawGraphBydistance]) {        return _distance;    } else {        return _time;    }}@end@implementation Graph- (ID)init  {    self = [super init];    if (self) {        NSMutableArray *array = [NSMutableArray array];        NSLog(@"before");        for (int i = 0; i < 100000; i++) {            GraphDataPoint *graphData = [[GraphDataPoint alloc] initWithYValue:@1 withTime:@1 withdistance:@1 withDelegate:self];            [array addobject:graphData];        }        NSLog(@"after");    }    return self;}- (BOol)drawGraphBydistance {    return YES;}@end
解决方法 系统需要跟踪存储指向对象的弱指针的每个存储器地址.为什么?因为如果要释放对象(它的内存将被释放),所有这些指针必须首先设置为nil.这就是使弱指针特殊的原因:它们不保留对象(不保持它们活着),但它们也永远不会悬挂指针(从不指向前者,现在死对象的内存地址);如果物体死亡,它们就会变成零.因此,每当弱引用的值发生变化时,系统必须首先告诉全局弱指针跟踪管理器删除过去记录的该内存地址的信息(如果有的话),然后在更改对象后记录新信息.不用说,整个事情必须是线程安全的,因此涉及(稍微昂贵)锁定.

__weak ID x;// ...x = anObject;// ...x = anotherObject;// ....x = nil;

事实上(并非真的,只是为了得到概念):

__weak ID x;// ...[WeakPointerTrackingManager lock];x = anObject;[WeakPointerTrackingManager var:&x pointsTo:anObject];[WeakPointerTrackingManager unlock];// ...[WeakPointerTrackingManager lock];x = anotherObject;[WeakPointerTrackingManager var:&x pointsTo:anotherObject];[WeakPointerTrackingManager unlock];// ...[WeakPointerTrackingManager lock];x = nil;[WeakPointerTrackingManager deleteInfoForVar:&x];[WeakPointerTrackingManager unlock];

assign没有那样做.只是存储对象的引用而不增加对象保留计数器.但是,如果对象死亡,assign变量仍然指向对象过去生存的内存地址.如果您现在向此不存在的对象发送消息,您的应用程序可能会崩溃或可能发生其他未定义的事情.

但严重的是,每个执行100,000次setDelegate调用的应用程序都被设计恕我直言.我想不出任何有意义的严重用例.在这里做任何你打算做的事情可能有更好的方法.

仅仅为了记录,访问弱变量也是昂贵的.

__weak ID x;// ...[x sendMessage];// ...__strong ID y; // Strong is optional,// vars are strong by defaulty = x;

事实上(并非真的):

__weak ID x;// ...__strong ID tmp;[WeakPointerTrackingManager lock];tmp = [x retain];[WeakPointerTrackingManager unlock];[tmp sendMessage];[tmp release];// ...__strong ID y;[WeakPointerTrackingManager lock];y = [x retain];[WeakPointerTrackingManager unlock];
总结

以上是内存溢出为你收集整理的ios – 弱房产的开销很大?全部内容,希望文章能够帮你解决ios – 弱房产的开销很大?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1074898.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存