我在我的项目中使用了一个外部库,该库是在ARC环境中构建的。根据库,只有当保留计数为0时,套接字对象才会被解除分配。据我所知,在ARC中不可能使用保留计数,但我被迫删除套接字对象的所有引用,这在我的项目中是不可能的。如何解决此问题?代码问题的要点如下:
-(void)callConnect{
for(int i = 0; i<[userArray count];i++){
[self connect:(NSString*)[userArray objectAtIndex:i]];
}
}
-(void)connect:(NSString *)username{
RTMPCLient *socket = [[RTMPClient alloc] init];
BroadCastClient *stream = [[BroadCastClient alloc] initWithClient:socket];
NSMutableDictionary *stream = [NSMutableDictionary dictionaryWithObject:stream forKey:username];
}
-(void)disconnect{
for(int i = 0; i<[userArray count];i++){
[stream objectForKey:[NSString stringWithFormat:@"%@",[userArray objectAtIndex:i]]] = nil; //error on this line
BroadCastClient *tempStream = [stream objectForKey:[userArray objectAtIndex:i]];
tempStream = nil;
}
}
我正在尝试使流对象为零,这会产生错误。无法将其保存为另一个变量,因为它增加了套接字对象的引用。将tempStream设置为nil不会影响创建的原始实例。我想在disconnect方法中从流中删除套接字对象的引用。我该怎么做?
ARC会将不可见的release
消息放在代码中(在连接中),但array
会对它们有强引用,因此它们会留在内存中。您在disconnect
中所要做的就是从集合([stream removeAllObjects]
和[userArray removeAllObjects]
)中删除所有对象,然后集合将释放它们
更新:
通过遵循您的代码,我看到以下内容:
在这段代码中,您正在创建BroadCastClient
的实例,并将其添加到NSDictionnary
(stream
)中,但NSDictionary没有引用它,因此它将在方法调用后被释放
-(void)callConnect{
for(int i = 0; i<[userArray count];i++){
[self connect:(NSString*)[userArray objectAtIndex:i]];
}
}
-(void)connect:(NSString *)username{
RTMPCLient *socket = [[RTMPClient alloc] init];
BroadCastClient *stream = [[BroadCastClient alloc] initWithClient:socket];
NSMutableDictionary *stream = [NSMutableDictionary dictionaryWithObject:stream forKey:username];
}
现在这里是disconnect
stream
字典(我不知道这个对象是什么,因为在你的代码中我看不到任何创建或添加到它的东西)对象BroadCastClient由字典保留,所以只需从字典中删除这个对象就可以将其从内存中释放出来(假设你没有其他强引用)
-(void)disconnect{
for(int i = 0; i<[userArray count];i++){
[stream objectForKey:[NSString stringWithFormat:@"%@",[userArray objectAtIndex:i]]] = nil; //error on this line
BroadCastClient *tempStream = [stream objectForKey:[userArray objectAtIndex:i]];
tempStream = nil;
}
}
我建议您对代码进行一些重构,但在此之前,请有一些时间阅读以下指南:https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/Articles/mmPractical.html
在ARC中,您只需将对象设置为零即可维护RC。所以你可以用下面的方法来做。
-(void)disconnect{
socket = nil;
stream = nil;
stream = nil;
}
-(void)connect:(NSString *)username{
if (socket != nil )
socket = nil;
RTMPCLient *socket = [[RTMPClient alloc] init];
if (stream != nil )
stream = nil;
BroadCastClient *stream = [[BroadCastClient alloc] initWithClient:socket];
NSMutableDictionary *stream = [NSMutableDictionary dictionaryWithObject:stream forKey:username]; // Make it using alloc...then you must use nil only
}
看起来stream
是NSMutableDictionary *
类型的实例变量。因此,如果你想删除stream
字典中的引用,你可以这样做:
- (void)disconnect {
for (int i = 0; i<[userArray count]; i++) {
[stream removeObjectForKey:[userArray objectAtIndex:i]];
}
}
// Alternative version using Fast Enumeration:
- (void)disconnect {
for (id key in userArray) {
[stream removeObjectForKey:key];
}
}
但是,如果您只想从stream
中删除所有引用,只需执行:
- (void)disconnect {
[stream removeAllObjects];
}