我开始在objective-c中更好地理解内存管理,但有些东西我不明白.这是一个属性声明:
@property (nonatomic, retain)UILabel *myLabel;
Run Code Online (Sandbox Code Playgroud)
这是它看不见的合成二传手(我认为):
- (void)setMyLabel:(UILabel *)newValue {
if(myLabel != newValue) {
[myLabel release];
myLabel = [newValue retain];
}
}
Run Code Online (Sandbox Code Playgroud)
这节省了你每次保留和填充的所有工作,但是说我第一次设置我的属性,它还没有被分配,所以它的引用数是0,对吧?所以我这样做
UILabel *tempLabel = [[UILabel alloc] init];
self.myLabel = tempLabel;
[tempLabel release];
Run Code Online (Sandbox Code Playgroud)
我不确定那里会发生什么,什么时候什么也没发布,但是说这个属性已经有了值,我们设置了它.在setter中,首先它被释放.那不是让它消失吗?如果它的引用计数是1,然后在它发布的setter中,它如何保持设置为保留的新值?
谢谢!!
众所周知,setTitle会自动保留作为参数传递的字符串.当需要更改按钮标题时,我想在设置新字符串之前必须释放当前(旧)字符串.我想知道点到它最优雅的方式是什么.
请参阅我的代码示例(此处,getPlayerHandFromGame方法生成自动释放的字符串,在调用setTitle时保留该字符串):
colourString = [pGame getPlayerHandFromGame:1 withColour:COLOUR_HEARTS];
// Split colourString into array of strings if not null.
if ([colourString length] != 0) {
listCards = [colourString componentsSeparatedByString:@" "];
for (cardCounterSameColour = 1; cardCounterSameColour <= [listCards count]; cardCounterSameColour ++) {
currentCardButton = [self buttonCardNumber:cardCounter];
// Objects are numbered from 0 in the array
[currentCardButton setTitle:[listCards objectAtIndex:cardCounterSameColour-1] forState:UIControlStateNormal];
cardCounter ++;
}
}
Run Code Online (Sandbox Code Playgroud)
由于按钮标题将多次更新,因此将多次调用此部分代码.我想在设置标题之前,我应该这样做:
[currentCardButton titleForState:UIControlStateNormal release]
Run Code Online (Sandbox Code Playgroud)
为了释放将不再使用的字符串(titleForState返回指向NSString的指针).
这是避免设备内存加载未使用的字符串的正确方法吗?
非常感谢,Apple92
你知道如果我保留一个自动释放的对象会发生什么吗?它会被释放还是保留获胜?
@propert(保留)做什么?它实际上并没有通过我的测试保留我的对象:
id obj = getObjectSomehow();
NSLog(@"%d", [obj retainCount]);
propertyWithRetain = obj;
NSLog(@"%d", [obj retainCount]);
// output:
// 1
// 1
Run Code Online (Sandbox Code Playgroud)
如何创建一个真正保留对象的属性?
是否可以保留子类的委托ASIHTTPRequest?
我做了一个ASIHTTPRequest被调用的子类JSONRequest.每个实例JSONRequest都是它自己的委托,处理回调,并将它们传递给它jsonDelegate,它是一个私有属性JSONRequest,并响应requestFinished:withResult:,其中result是NSDictionaryJSON响应的表示.要做到这一点,我重载setDelegate:在JSONRequest做super.delegate = self; self.jsonDelegate = newDelegate.
jsonDelegate在这种情况下保留是否可以,因为通常jsonDelegate是一个视图控制器,如果用户点击"返回"等,有时会在加载请求时解除分配.我将jsonDelegate在JSONRequest调用回调方法后释放.
我怎么知道这没关系,也不会导致保留循环.
我正在创建一个iPad游戏,它有一个viewController,可以从nib文件加载到它的视图中.视图中有一堆按钮,我通过界面构建器链接到UIButton*变量(因此每个按钮链接到一个不同的变量).我们在其中一个按钮(使用我的第一个按钮变量,b1)上加载了笔尖后立即检查了保留计数,它给了我一个值2.任何人都可以解释为什么它是2?在笔尖加载后保留它的两件事是什么?
而现在我更加困惑,因为在我的dealloc函数中,我单独释放了每个按钮变量,然后检查其中一个按钮变量的保留计数,它仍然是STILL 2!它至少应该降到1,不应该有吗?我应该在dealloc函数中多次发布它吗?如果是这样,有多少?
谢谢
例如:
@interface DataMode : NSObject {
NSString * name;
}
@property (nonatomic, retain) NSString * name;
@end
Run Code Online (Sandbox Code Playgroud)
将编译器自动添加[name release]到-dealloc?
- (void) dealloc
{
[name release]; // if we don't add it , will the compiler add "[name release]"???
[super release];
}
Run Code Online (Sandbox Code Playgroud) 我有一个名为JSONNetworkUtility的服务对象,我将它作为ivar存储在我的模型中,以及具有相同名称,非原子和保留的合成属性:
myNetworkUtility = [[JSONNetworkUtility alloc] initNetworkConnectionWithURL:urlString withQueryString:nil delegate:self];
Run Code Online (Sandbox Code Playgroud)
该委托包括两个回调,一个是networkUtility:didFailWithError:,另一个是networkUtility:didFinishWithData:.奇怪的是该属性导致一些奇怪的错误:
- (void)networkUtility:(JSONNetworkUtility *)networkUtility didFinishWithData:(NSArray *)jsonArray
{
NSLog(@"myNetworkUtility = %@", myNetworkUtility);
// returns <JSONNetworkUtility: 0x3944450>
NSLog(@"networkUtility = %@", networkUtility);
// also returns <JSONNetworkUtility: 0x3944450>
NSLog(@"self.myNetworkUtility = %@", self.myNetworkUtility);
// fails and throws an NSZombie error!
}
Run Code Online (Sandbox Code Playgroud)
我在该行上得到的错误是:
*** - [MyModel myNetworkUtility]:发送到解除分配的实例0x148190的消息
我完全难过了!关于为什么它在吸气器上失败的任何线索?为什么它会返回一个完全不同的对象?
我使用getter的原因是因为我想使用self.myNetworkUtility = nil所以我可以用一个新对象在属性的顶部写,但我已经把它切回到这个跟踪,我仍然有问题......
谢谢!
在非ARC应用程序中,我有一个NSOperation子类,它由一个委托排队,看起来像:
// note that the delegate and element properties are retained
-(id)initWithDelegate:(id<SomeDelegate>)inDelegate element:(SomeElement *)inElement
{
if (self = [super init])
{
[self setDelegate:inDelegate];
[self setElement:inElement];
}
}
-(void)dealloc
{
[_delegate release];
[_element release];
[super dealloc];
}
-(void)main
{
// do stuff
dispatch_async(dispatch_get_main_queue(), ^{
[[self delegate] doSomething:[self element]];
});
}
Run Code Online (Sandbox Code Playgroud)
由于[[self delegate] doSomething:[self element]]将在我的NSOperation对象可能被解除分配后被调用,在将此操作添加到队列之前,是否需要确保在委托中保留"element"?元素对象保留在应用程序的其他位置,但可能会在那里释放.我需要确保当我的代表从NSOperation收回它时,它仍然是一个有效的对象.
只是想知道在dispatch_async中调用它的行为是否会保留传递给它的参数.我当然可以使用NSInvocation和performSelectorOnMainThread来保留它.
objective-c ×9
retain ×9
iphone ×4
properties ×2
assign ×1
autorelease ×1
dealloc ×1
delegates ×1
ios ×1
ipad ×1
nsoperation ×1
release ×1
uibutton ×1