Objective c NSObject未保留

Objective c NSObject未保留,objective-c,function,class,nsobject,retain,Objective C,Function,Class,Nsobject,Retain,过程- NSObject类,用于生成具有特定属性的卡。这将添加到可变数组中并相应地使用。但是,在函数确定另一个类中的手动结果后,MutableArray将丢失其所有值 现在我知道一个可变数组只是指向对象,而不是保持它们,所以为了让它失去所有的值,我假设对象被圆弧扫向 -(void)rankHand { NSString *echo = [Hand returnHandRank:_hand withString:false]; // 7 values in _hand // 0 v

过程-

NSObject类,用于生成具有特定属性的卡。这将添加到可变数组中并相应地使用。但是,在函数确定另一个类中的手动结果后,MutableArray将丢失其所有值


现在我知道一个可变数组只是指向对象,而不是保持它们,所以为了让它失去所有的值,我假设对象被圆弧扫向

-(void)rankHand {
    NSString *echo = [Hand returnHandRank:_hand withString:false]; // 7 values in _hand
    // 0 values in _hand.
    NSLog(@"%@", echo);

}
在中断以查看问题后,在returnHandRank:withString:

returnHandRank:withString:是Hand类中的一个很长的函数。这就是为什么我认为他们没有被保留

有人能详细说明吗?我认为再从牌组中添加牌是没有意义的,这是最好的解决方案吗

编辑:添加了returnHandRank:withString:

最近有一些关于组合的问题,所以除非你正在创建帐户,否则我们怀疑有家庭作业正在进行中。。。没问题,让我们看看能不能给你指出正确的方向。然而,我们不能回答这个问题,不是因为它可能是家庭作业,而是因为没有足够的信息来回答

现在我知道一个可变数组只是指向对象,而不是保持它们

到目前为止是正确的


所以为了让它失去所有的值,我假设物体被弧线扫过

-(void)rankHand {
    NSString *echo = [Hand returnHandRank:_hand withString:false]; // 7 values in _hand
    // 0 values in _hand.
    NSLog(@"%@", echo);

}
但现在完全错了:-您误解了Objective-C中的自动内存管理是如何工作的。首先,现代基于ARC的管理是关于所有权的——存储引用的变量是否声明对引用引用对象的所有权。当它确实声明所有权时,变量的属性为“强”,当它存储引用但不声明所有权时,它的属性为“弱”。您稍后会遇到一些其他所有权属性,暂时可以忽略它们。默认情况下,对象引用变量具有strong属性

让我们打个比方:

考虑气球物体,它会漂浮,除非它被压住;还有一个手动变量,用来保存东西。 许多不同的手可以握住连接到同一气球的字符串引用。 如果手紧紧地抓住绳子,气球就不能漂走。 如果绳子刚好放在手掌上,气球就会飘走,除非至少另一只手紧紧握住另一根绑在气球上的绳子。 只要至少有一只手紧紧握住绳子,气球就不会飘走。 弧线是微风,它吹走了没有紧紧抓住的气球。 未注变量默认为strong,因此当引用存储在其中时,该变量将声明被引用对象的所有权,并且不会被ARC清除。类的实例变量或标准强属性都声明所有权。所有标准集合、数组、字典、集合都对集合中存储的引用所引用的对象声明所有权

因此,如果将引用存储在NSMutableArray中,只要引用保留在数组中,被引用对象就不会被ARC清除。如果对数组进行变异并删除引用,则当且仅当强变量中未存储对该数组的其他引用时,该数组引用的对象将通过ARC循环返回到可用内存池

只要对数组的引用存储在强变量中,数组本身就会一直存在。当数组没有强引用时,ARC将回收数组本身,在此过程中,存储在数组中的所有引用将被删除,如果这些引用是引用对象的最后一个强引用,它们也将被回收

希望这有助于理解它是如何工作的,这将帮助您找到清空数组或丢失对数组本身的所有强引用的位置;e、 g.为引用数组的变量分配一个新的引用或nil

现在让我们看看您的一些代码:

NSArray *suits = [[NSArray alloc] initWithObjects:@"h",@"d",@"c",@"s", nil];
[NSNumber numberWithInt:41]
这是旧式语法,您可以使用数组文字@[…]更轻松地创建NSArray:

不存在NSMutableArray文字,因此您可以使用NSArray文字来创建可变副本:[@[…]mutableCopy]或更短的@[…]字符。对于后者的使用,mutableCopy的意见不同。NSNumber对象还有一个文本,即您的代码:

NSArray *suits = [[NSArray alloc] initWithObjects:@"h",@"d",@"c",@"s", nil];
[NSNumber numberWithInt:41]
可以简单地用@41替换

使用上述文字将使代码更短,更易于阅读

现在请你发言:

card.face = [NSString stringWithFormat:@"%@", faces[i % 13]];
表示对引用和不可变对象如何工作的误解。NSString对象是不可变的,一旦创建,其值将永远不会更改。stringWithFormat方法:根据其格式和参数构造NSString,在本例中,它是单个字符串,因此您只需复制等效于以下内容的字符串:

card.face = [faces[i % 13] copy];
card.face = faces[i % 13];
然而,不可变对象的副本只是原始对象 发射型计算机断层扫描仪。您知道,当您使用字符串文字创建面时,面仅包含不可变字符串,因此上述内容相当于:

card.face = [faces[i % 13] copy];
card.face = faces[i % 13];
重要提示:您可以通过子分类将可变NSMutableString引用用作NSString one,因此,只有当您知道引用是NSString对象而不是NSMutableString对象时,此处删除副本的最后一步才有效

在面上使用直接索引后,您可以切换到长格式:

card.prime = [[primes objectAtIndex:(i % 13)] intValue];
在其他一些地方。它们都可以用[…]代替,例如:

当您使用I/13和余数I% 13时都是正确的,您可能需要考虑使用两个嵌套循环来避免它们,例如:

for(int suitRank = 0; suitRank < 4; suitRank++)
{  for(int cardRank = 0; cardRank < 13; cardRank++)
   {  // now use suitRank for i / 13 and cardRank for i % 13
永远不要这样做!虽然id已被使用,但它会降低编译器检查代码是否正确的能力,并可能导致在运行代码时出现编译器可能捕捉到的简单错误。在这里,发送方显然是对可变数组的引用,声明如下:

+ (NSMutableArray *)createDeck:(NSMutableArray *)sender
{
   [sender removeAllObjects];
应用上述文字后,您将拥有:

NSMutableArray *fiveCardHand = @[ cards[[pointerArray[0] intValue]],
                                  ...
                                ].mutableCopy;
//Check for hand rank.

fiveCardHand = [self organizeCardsRankOrder:fiveCardHand];
给你:

创建可变数组 将其引用分配给fiveCardHand 使用organizeCardsRankOrder的结果覆盖fiveCardHand中的引用: 因此,这里您似乎没有对fiveCardHand引用的数组进行变异,而是将变量更改为引用不同的数组。您不需要使用可变数组来实现这一点,您是在变异包含引用的变量,而不是引用的数组。此处使用的是Now Aspect,因为您没有提供organizeCardsRankOrder:的代码,可能该方法确实会对传递给它的数组进行变异,如果是这种情况,则不需要同时返回该数组,也不需要为变量赋值。因此,请仔细查看您的代码,确定您是在变异数组还是仅仅是变量,并相应地进行更改

最后,您不需要在问题中提供任何声明。通过命名约定,您可能直接访问属性的支持变量,这样做通常是最好避免的,或者访问实例变量,两者都是一些未指定的类。因此,我们无法提供任何真正的帮助,只需检查它们是否连接到您在任何地方都使用同一实例的实例-一个常见的早期错误是在一个实例中设置实例变量,尝试从另一个实例读取它,然后想知道为什么值不同


嗯,调试愉快

所以它失去了所有的值,我假设物体被弧线扫过,你错了。如果发生这种情况,那是没有意义的。显然,如果一个对象已添加到数组中,数组将保留该对象。-听起来像是你的returnHandRank:withString可能不会做你认为它会做的事情。但出于某种原因,你选择了不表现出来,即使你自己说这是问题的核心。“这就很难帮上忙了。”马特:嗯,我觉得这是引用语义。然而,如果你说我错了,我想我错了。我已经在上面的问题中添加了这个函数。在哪里声明了_hand实例变量?它被分配到哪里?它可能被一个空数组覆盖了…感谢您的深入回复。我很感激。不幸的是,这不是家庭作业,这只是我想尝试的东西。我已经一两年没有正确编程了,所以我只是想重新开始。我也没有学过任何编程,我在2007年左右自学了PHP,然后进入了Objective-C。因此,我的模式通常来自内存,而不是逻辑。不过,谢谢你的回答,虽然它不一定能回答预期的问题,但我会接受它,因为显然没有从中得出答案。
NSMutableArray *fiveCardHand = @[ cards[[pointerArray[0] intValue]],
                                  ...
                                ].mutableCopy;
//Check for hand rank.

fiveCardHand = [self organizeCardsRankOrder:fiveCardHand];