ARC des collisions liées à iOS lors de l'utilisation d'un pointeur de bloc comme une variable membre
Quelqu'un peut s'il vous plaît aider avec l'ARC et la mémoire des blocages liés à l'?
J'ai la classe LTRequest
avec un membre de la variable qui stocke un pointeur de bloc:
typedef void (^APICallOKBlock)(id);
@interface LTRequest : NSObject
@property (nonatomic, strong) APICallOKBlock okCB;
@end
Le code d'initialisation de cette variable:
-(void)addOKBlock:(APICallOKBlock)okBlock
{
self.okCB = okBlock;
}
J'appelle le bloc en cas de succès:
-(void)apiCallCompletedWithResult:(id)result
{
if(self.okCB != nil)
{
self.okCB(result);
}
}
Pour référence, le bloc ressemble à quelque chose comme ceci:
APICallOKBlock okBlock = ^(id result)
{
[self handleAPICallCompleted:result];
};
Il appelle une fonction définie dans l'objet qui a planifié l'appel d'api, toutefois, la partie n'est pas important. L'Important est ce qui se passe quand apiCallCompletedWithResult
est appelée après l'appel de l'api a été couronnée de succès. Et ce qui se passe est que le bloc est appelé, mais l'application se bloque peu de temps après, lorsque l'objet de la requête LTRequest
obtient libéré (SomeAppName est notre application):
Thread 6 name: Dispatch queue: com.apple.root.low-priority
Thread 6 Crashed:
0 libobjc.A.dylib 0x300bad9c objc_release + 12
1 libobjc.A.dylib 0x300c6c00 objc_storeStrong + 24
2 SomeAppName 0x00055688 -[LTRequest .cxx_destruct] (LTRequest.m:12)
3 libobjc.A.dylib 0x300bba66 object_cxxDestructFromClass + 50
4 libobjc.A.dylib 0x300bba2c object_cxxDestruct + 8
5 libobjc.A.dylib 0x300b99ac objc_destructInstance + 20
J'ai essayé d'utiliser unsafe_unretained
au lieu de strong
pour stocker le bloc dans la LTRequest
objet:
@property (nonatomic, unsafe_unretained) APICallOKBlock okCB;
Dans ce cas, le crash se passe exactement dans la ligne avec le si:
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x300b9eda objc_retain + 10
1 libobjc.A.dylib 0x300c6bde objc_retainAutoreleasedReturnValue + 34
2 SomeAppName 0x00054f90 -[LTRequest apiCallCompletedWithResult:] (LTRequest.m:84)
3 SomeAppName 0x0002f8aa __29-[LTServerProxy makeAPICall:]_block_invoke_0 (LTServerProxy.m:154)
//file LTRequest.m
line 84 if(self.okCB != nil)
line 85 {
line 86 self.okCB(result);
line 87 }
Suis-je utiliser le pointeur vers un bloc correctement et comment dois-je l'appeler pour ne pas causer de tout les crashs?
Quelques infos: je suis en utilisant SDK iOS 5.0, cible de déploiement est 4.0, un appareil iPhone, et l'ARC est activé pour l'ensemble du projet.
OriginalL'auteur Amiramix | 2012-01-13
Vous devez vous connecter pour publier un commentaire.
Vous souhaitez que la propriété d'être
copy
plutôt queretain
:blog.refractalize.org/post/10476042560/... a quelques notes sur pourquoi c'est le cas, et un lien vers le même article plus détaillé.
Ce qui m'a sauvé! J'ai eu un NSNumber que j'avais accidentellement marqué comme nonatomic, céder à la place de nonatomic, forte! Grande différence! Merci!
Vous m'avez sauvé 😛
OriginalL'auteur mattjgalloway
Vous devez copier le bloc lors de l'enregistrement de son instance de l'instance de classe.
OriginalL'auteur dtuckernet