李岡諭*_*李岡諭 0 objective-c automatic-ref-counting
下ARC,编译器将禁止使用任何方法或选择器-retainCount,-retain,-dealloc,-release,和-autorelease.
但有时我想知道运行时的保留计数,或者使用方法调配来交换-deallocNSObject 的方法来做某事.
是否有可能抑制(或绕过)编译器抱怨几行代码?我不想为整个项目或整个文件修改ARC环境.我认为预处理器可以做到,但是怎么做?
谢谢你们给我一个关于使用的教训-retainCount.但我想知道是否可以强制调用/使用那些禁止的方法/选择器.
我知道这Instruments是完成这项工作的有力工具.但我对这些问题仍然很好奇.
-retainCount:使用块时,如果未__weak在外部变量上指定标识符,则在将块复制到堆中后,块将自动保留块中的外部对象.因此,您需要使用弱自我来避免保留周期,例如:
__weak typeof(self) weakSelf = self;
self.completionBlock = ^{
[weakSelf doSomething];
};
Run Code Online (Sandbox Code Playgroud)
但是,当您仅在复制的块中使用实例变量时,它仍将导致保留周期(YES,尽管您未self在块中使用任何关键字).
例如,在非ARC下:
// Current self's retain count is 1
NSLog(@"self retainCount: %d", [self retainCount]);
// Create a completion block
CompletionBlock completionBlock = ^{
// Using instance vaiable in the block will strongly retain the `self` object after copying this block into heap.
[_delegate doSomething];
};
// Current self's retain count is still 1
NSLog(@"self retainCount: %d", [self retainCount]);
// This will cuase retain cycle after copying the block.
self.completionBlock = completionBlock;
// Current self's retain count is 2 now.
NSLog(@"self retainCount: %d", [self retainCount]);
Run Code Online (Sandbox Code Playgroud)
如果不在-retainCount复制的块代码之前/之后使用,我认为很容易发现在完成块中使用实例变量导致的保留周期.
-dealloc:我想知道是否可以使用方法调配来监视在-dealloc调用Xcode控制台时通过在Xcode控制台上记录消息来释放哪个对象.我想,以取代原来的执行-dealloc的NSObject.
Ant*_* MG 23
这根本没有推荐,我不知道你的意图,但他们听起来不太安全.
使用的retainCount是不推荐.
来自AppleDocs:
此方法在调试内存管理问题时没有任何价值.因为任何数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上保留任意数量的延迟版本,所以您不太可能从此获取有用信息方法
而且,如果有任何疑问,请查看此链接:
http://whentouseretaincount.com/
无论你想做什么,请不要.
对于将来的参考,我将添加一些linsk来帮助您了解内存在iOS中的工作方式.即使您使用ARC,也必须知道(请记住,ARC不是垃圾收集器)
当然,一旦你理解了记忆是如何工作的,就是学习如何用仪器来描述它的时候了:
与其他评论者100%同意您不想使用的事实-retainCount.但是,关于你的另一个问题-dealloc:
你也不想慌乱-dealloc.如果你认为你想要调整它,你就不明白它是如何工作的.那里有很多优化; 你不能只是搞乱它.但是,正如@bbum提示的那样,当对象被释放时,您可以轻松获得通知,这非常有用.
将关联对象附加到要监视的对象.当您想要观看的内容消失时,相关对象也会消失,您可以覆盖它dealloc以执行您想要的任何操作.显然你需要小心一点,因为你处于中间位置dealloc,但你通常可以做任何你需要的东西.最重要的是,对于许多情况,您可以在此处设置断点或添加日志记录语句,以便查看对象的发布位置.这是一个简单的例子.
const char kWatcherKey;
@interface Watcher : NSObject
@end
#import <objc/runtime.h>
@implementation Watcher
- (void)dealloc {
NSLog(@"HEY! The thing I was watching is going away!");
}
@end
NSObject *something = [NSObject new];
objc_setAssociatedObject(something, &kWatcherKey, [Watcher new],
OBJC_ASSOCIATION_RETAIN);
Run Code Online (Sandbox Code Playgroud)
const char kWatcherKey;
@interface Watcher : NSObject
- (void)lastRetainDone;
@end
#import <objc/runtime.h>
// turn off ARC!
@implementation Watcher
{
BOOL noMoreRetainsAllowed;
}
- (void)lastRetainDone {
noMoreRetainsAllowed = YES;
}
- (id) retain {
if (noMoreRetainsAllowed) abort();
return [super retain];
}
- (void)dealloc {
NSLog(@"HEY! The thing I was watching is going away!");
[super dealloc];
}
@end
...
NSObject *something = [NSObject new];
Watcher *watcher = [Watcher new];
objc_setAssociatedObject(something, &kWatcherKey, watcher,
OBJC_ASSOCIATION_RETAIN);
[watcher lastRetainDone];
[watcher release];
Run Code Online (Sandbox Code Playgroud)
现在,当它something消失时,-[Watcher dealloc]会为你开火并登录.很容易.完全支持和记录.
编辑:
如果不在复制的块代码之前/之后使用-retainCount,我不认为在完成块中使用实例变量导致的保留周期将很容易被发现.
你在这里有点正确,但是有两个教训需要学习,也没有使用retainCount(在这种情况下实际上对你没有帮助,因为这retainCount通常是你不期望的事情).
| 归档时间: |
|
| 查看次数: |
1486 次 |
| 最近记录: |