我一直在通过我的应用程序试图处理所有的内存问题和阅读内存管理.我开始使用[object retainCount]来跟踪我的内存分配.这是否值得信任,因为我一直觉得这些计数真的很奇怪?
有人可以解释以下内容:
请记住,这个app委托和一个空的mainViewController没有任何区别.initWithRootViewController导致计数上升,但我没有看到添加一个的另一种方法....
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/* Create the View Controllers */
UIViewController *mainViewControl = [[[MainViewController alloc] init] autorelease];
/* Create the Navigation Controller */
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:mainViewControl] autorelease];
NSLog(@"retain count: %i",[mainViewControl retainCount]);
/* Set the toolbar to purple */
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
navigationController.navigationBar.tintColor = [UIColor colorWithRed:.6 green:.1 blue:.4 alpha:0.4];
navigationController.navigationBar.translucent = YES;
NSLog(@"retain count: %i",[mainViewControl retainCount]);
navigationController.toolbar.barStyle = UIBarStyleBlackTranslucent;
navigationController.toolbar.tintColor = [UIColor colorWithRed:.6 green:.1 blue:.4 alpha:0.4];
navigationController.toolbar.translucent = YES;
[navigationController setNavigationBarHidden:YES animated:NO]; …Run Code Online (Sandbox Code Playgroud) 我只是想知道:如果将对象的保留计数添加到Objective-C中的数组或字典中,它是否会增加?将数据添加到数组或字典后,我可以立即释放它吗?
我知道我的问题已经在StackOverflow上讨论过,但我发现答案不能完全满足我的需求.所以问题是:
NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];
Run Code Online (Sandbox Code Playgroud)
现在,secondArray的保留计数是多少?2还是1?我应该发布两次还是只发一次?copy或mutableCopy是否会增加COPYING(此事件中为secondArray)对象的保留计数?
当我使用copy时保留了什么,保留NSString属性并将其分配给局部变量?
@interface SomeClass : NSObject
{
NSString *name;
NSString *name2;
}
@property (nonatomic, retain) NSString* name1;
@property (nonatomic, copy) NSString *name2;
Run Code Online (Sandbox Code Playgroud)
如果我将string的值赋给另一个NSString变量,如:
NSString *newString1 = name1;
NSString *newString2 = name2;
Run Code Online (Sandbox Code Playgroud)
什么将保留name1和name2的数量?
NSString *anotherString1 = [NSString alloc]initWithString:name1];
NSString *anotherString2 = [NSString alloc]initWithString:name2];
Run Code Online (Sandbox Code Playgroud)
这里名字1和名字2的保留计数是多少?
当启用时ARC,以下代码使得物镜对于保留两次块通过调用objc_retain()和objc_retainBlock().(因此retainCount块定义后变成3).
我检查了obj不在自动释放池中,并且在方法结束时有两个objc_release()调用obj.(我知道计数保留没有意义,但我正在检查objc_retain()调用,而不是几乎没有检查保留计数.)这背后的基本原理是什么?
-(void)myMethod
{
NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj %@ retaincount %ld", obj, CFGetRetainCount((__bridge CFTypeRef)obj));
void (^myBlock)(void) = ^()
{
NSLog(@"obj %@ retaincount %ld", obj, CFGetRetainCount((__bridge CFTypeRef)obj));
};
NSLog(@"obj %@ retaincount %ld", obj, CFGetRetainCount((__bridge CFTypeRef)obj));
myBlock();
}
Run Code Online (Sandbox Code Playgroud)
仅仅保留obj一次以便通过块捕获它是不够的?
注意:此外,当我删除myBlock变量并调用它时,所以只使用^(){...}定义并且永远不会调用该定义,obj仍然保留objc_retain(),这看起来很奇怪.我正在使用XCode 4.3.2.
memory-management objective-c retain retaincount objective-c-blocks
当我使用__weak指针引用NSObject时,会显示意外的retainCount.
这是代码:
id obj1 = [[NSObject alloc] init];
id __weak obj2 = obj1;
NSLog(@"obj1: %ld", CFGetRetainCount((__bridge CFTypeRef)obj1)); // line 31
NSLog(@"obj2: %ld", CFGetRetainCount((__bridge CFTypeRef)obj2)); // line 32
NSLog(@"obj1 again: %ld", CFGetRetainCount((__bridge CFTypeRef)obj1)); // line 33
Run Code Online (Sandbox Code Playgroud)
所以〜我的困惑是,obj2的retainCount预计为1,为什么retainCount为2?
我从书中读到:__ weak指针将对象注册到autoreleasepool,因此保留计数+ 1.
但是,obj1和obj2指的是相同的内存地址,在这种情况下,obj1的retainCount也应该变为2.但是,它仍然保持为1.
我知道retainCount是不可靠的,但我很好奇它是如何来的.(我的环境是Xcode 8.3.3,iOS 10.3)
非常感谢任何人都可以向初学者解释这个:)
NSMutableString *ms = [[NSMutableString alloc]init];
[ms appendFormat:@"element %ld",1];
[ms appendFormat:@"element %ld",2];
NSMutableString *ms2 = [ms mutableCopy];
NSLog(@"ms retain count:%lu",ms.retainCount);
NSLog(@"ms2 retain count:%lu",ms2.retainCount);
NSValue *sw = [NSValue valueWithNonretainedObject:ms2];
NSMutableArray *a = [NSMutableArray array];
[a addObject:ms];
[a addObject:sw];
NSLog(@"ms retaincount %lu",ms.retainCount);
NSLog(@"ms2 retaincount %lu",ms2.retainCount);
Run Code Online (Sandbox Code Playgroud) 在这里我得到了一些丑陋的代码:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy"];
NSDate *date = [NSDate date];
NSString *textWithYear = [NSString stringWithFormat:@"text and year %@", [dateFormatter stringFromDate:date] ];
[dateFormatter release];
NSLog(@"%i", [dateFormatter retainCount]); // returns 1 !
Run Code Online (Sandbox Code Playgroud)
如您所见,保留计数器返回1,我想这意味着该对象未被释放.如果我将该字符串更改为
[dateFormatter release], dateFromatter = nil;
Run Code Online (Sandbox Code Playgroud)
保留计数器返回0,这应该是因为它无法计算nil的保留:)
有什么东西我不了解保留计数器,或者这个对象真的没有发布?当我release第二次发送它(努力获得零保留计数)时,它会预期粉碎:)
还有一个问题:如果dateFormatter真的被释放了,为什么当我调用[dateFormatter retainCount]时它不会崩溃?
我注意到在将我的Xcode更新为4.2之后,retainCount总是等于-1.我不在我的项目中使用ARC,我甚至尝试在项目设置中创建新项目并将ARC选项切换为关闭,但下一行的工作非常奇怪:
NSString *string = [[NSString alloc] init];
NSLog(@"%i", [string retainCount]); //-1
[string retain];
[string retain];
[string retain];
NSLog(@"%i", [string retainCount]); //still -1
[string release];
[string release];
[string release];
NSLog(@"%i", [string retainCount]); //still -1
Run Code Online (Sandbox Code Playgroud)
我想念一下吗?我认为如果关闭ARC选项,项目将像以前一样完全正常工作.
SWIFT代码
override func viewDidLoad() {
super.viewDidLoad()
var v1 = ViewController()
let v2 = ViewController2()
print("\(CFGetRetainCount(v1)) and \(CFGetRetainCount(v2))")
}
Run Code Online (Sandbox Code Playgroud)
在Swift引用计数打印为2和2
目标C代码
- (void)viewDidLoad {
[super viewDidLoad];
ViewController *v1 = [[ViewController alloc]init];
ViewController2 *v2 = [[ViewController2 alloc]init];
NSLog(@"%ld and %ld",CFGetRetainCount((__bridge CFTypeRef)(v1)),CFGetRetainCount((__bridge CFTypeRef)(v2)));
}
Run Code Online (Sandbox Code Playgroud)
在Objective C中,引用计数打印为1和1
为什么参考计数在目标c和swift中有所不同?
retaincount ×10
objective-c ×8
ios ×4
copy ×2
retain ×2
iphone ×1
nsarray ×1
nsdictionary ×1
null ×1
swift ×1
xcode4.2 ×1