CoreData属性的setter是否保留?或复制价值或什么是二传手?我想知道是否必须(自动)释放我放入setter的值.
我已经做了一些快速测试.假设以下型号:
+----------+
| Class A |
+----------+
| v :int32 |
+----------+
Run Code Online (Sandbox Code Playgroud)
生成的ManagedObject然后如下所示:
//A.h
@interface A : NSManagedObject
{
}
@property (nonatomic, retain) NSNumber * v;
//...
//A.m
@implementation A
@dynamic v;
...
Run Code Online (Sandbox Code Playgroud)
好的,属性标记为retain,因此如果我将NSNumber设置为v,则应保留NSNumber.但它不是(我认为).我做了以下事情:
A *a = ... ;
NSNumber *retainCheck = [[NSNumber alloc] initWithInt:23];
NSLog(@"retainCheck1: %i",[retainCheck retainCount]);
a.v = retainCheck;
NSLog(@"retainCheck2: %i",[retainCheck retainCount]);
NSLog(@"retainCheck3: %i",[a.v retainCount]);
NSLog(@"pointer1: %#x",retainCheck);
NSLog(@"pointer2: %#x",a.v);
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
retainCheck1: 1
retainCheck2: 1
retainCheck3: 1
pointer1: 0x62f068
pointer2: 0x62f068
Run Code Online (Sandbox Code Playgroud)
两个NSNumber都是相同的NSNumber实例(相同的指针值 - >所以它没有复制或类似的那样),并且设置器似乎不保留NSNumber.
我做的...... 我的测试错了吗?或者NSManagedObject-setters的行为与标题中描述的不一样? …
当我使用__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)
非常感谢任何人都可以向初学者解释这个:)
我创建了一组相同的自定义类型的对象.所有对象都具有方法showDeleteButton了hideDeleteButton.我发现当我隐藏删除按钮(删除它)按钮时,按下了retainCounter == 2.
这里的代码:
-(void)showDeleteButton {
if(!isDeleteButtonLoaded) { // Check that method was't triggered twice
UIButton *aDeleteButton = [[UIButton alloc] initWithFrame:CGRectMake(-3, -7, 30, 29)]; // RC == 1
[aDeleteButton setImage:[UIImage imageNamed:@"close_button.png"] forState:UIControlStateNormal];
[self addSubview:aDeleteButton]; // RC == 2
[aDeleteButton addTarget:self action:@selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
deleteButton = aDeleteButton;
[aDeleteButton release]; // RC == 1
isDeleteButtonLoaded = YES;
NSLog(@"delete button retain count (created): %d", [deleteButton retainCount]);
[self setNeedsDisplay];
}
Run Code Online (Sandbox Code Playgroud)
}
-(void)deleteButtonPressed:(id)sender {
[delegate deleteImageAtPath:self.imageFullPath];
Run Code Online (Sandbox Code Playgroud)
}
-(void)hideDeleteButton {
if(isDeleteButtonLoaded) {
NSLog(@"delete …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选项,项目将像以前一样完全正常工作.
我需要知道retaincount对象是否应该总是0如果我想在我的代码中有一个良好的内存管理.我从一本书中得到了以下代码.并且有一个声明NSLog叫做after release = 2,那么我是否应该再释放2次以使其retaincount为0?
#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSValue.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSNumber *myInt = [NSNumber numberWithInteger: 100];
NSNumber *myInt2;
NSMutableArray *myArr = [NSMutableArray array];
NSLog (@”myInt retain count = %lx”,
(unsigned long) [myInt retainCount]);
[myArr addObject: myInt];
NSLog (@”after adding to array = %lx”,
(unsigned long) [myInt retainCount]);
myInt2 = myInt;
NSLog (@”after …Run Code Online (Sandbox Code Playgroud) 我将手动管理NSMutableDictionay的内存,而不使用自动释放.并且mutableDictonary中的每个对象都是NSArray,每次我在mutableDictionary中添加一个数组时,我将使用
NSArray *newArray = [[NSArray arrayWithArray:anArray] retain]
[mutableDict setObject:newArray forKey:@"aKey"];
Run Code Online (Sandbox Code Playgroud)
问题是,我怎么能保证没有内存泄漏?我在dealloc中直接使用[mutableDict release]是好的吗?mutableDict的retainCount是否等于其对象的所有retainCounts(保留的数组)的总和?
memory-management objective-c nsmutabledictionary retaincount
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中有所不同?
通过简单的保留/释放方案查看此代码片段:
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@end
@implementation SomeClass
@end
int main(int argc, const char * argv[])
{
SomeClass *aClass = [[SomeClass alloc] init];
NSLog(@"retainCount: %lu", [aClass retainCount]);
[aClass retain];
NSLog(@"retainCount: %lu", [aClass retainCount]);
[aClass release];
NSLog(@"retainCount: %lu", [aClass retainCount]);
[aClass release];
NSLog(@"retainCount: %lu", [aClass retainCount]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是结果输出:
2013-04-29 17:33:50.695 retainCount: 1
2013-04-29 17:33:50.697 retainCount: 2
2013-04-29 17:33:50.697 retainCount: 1
2013-04-29 17:33:50.698 retainCount: 1
Run Code Online (Sandbox Code Playgroud)
最后一个retainCount应为"0"或应用程序崩溃.为什么结果为"1"?!
objective-c ×8
retaincount ×7
ios ×3
iphone ×2
cocoa-touch ×1
core-data ×1
memory-leaks ×1
null ×1
swift ×1
xcode4.2 ×1