ARC proíbe objetos Objective-C em structs ou uniões, apesar de marcar o arquivo -fno-objc-arc

85

ARC proíbe objetos Objective-C em structs ou uniões, apesar de marcar o arquivo -fno-objc-arc? Porque isto é assim?

Presumi que, se você marcar -fno-objc-arc, você não terá essa restrição.

Zsolt
fonte

Respostas:

170

Se você recebeu esta mensagem, tente __unsafe_unretained. Só é seguro se os objetos na estrutura não forem retidos. Exemplo: Se você usar OpenFeint com ARC, a classe OFBragDelegateStrings informa esse erro em uma estrutura.

typedef struct OFBragDelegateStrings
{
     NSString* prepopulatedText;
     NSString* originalMessage;
} OFBragDelegateStrings;

para

typedef struct OFBragDelegateStrings
{
     __unsafe_unretained NSString* prepopulatedText;
     __unsafe_unretained NSString* originalMessage;
} OFBragDelegateStrings;
Zeiteisen
fonte
4
ele também cria problemas quando eu aloco a string, ele mostra um aviso ao atribuir o objeto retido ao objeto variável unsafe_unretained será liberado após a atribuição. E quando eu uso ele trava
Deepak Singh Negi
8
Isso não resolve todos os problemas, o objeto normalmente seria liberado imediatamente e, portanto, indisponível.
Diziet
sim - isso não funciona realmente ... a solução é de alguma forma desligar o ARC para um arquivo de origem derivado que eu não consegui descobrir ainda ...
nielsbot
1
Você faz isso adicionando o sinalizador -fno-objc-arc ao arquivo na fase de construção.
Abizern,
E se o campo struct for apenas uma "referência burra" e o objeto estiver realmente sendo retido (possuído) em outro lugar (digamos, dentro de um NSArray)? Nesse caso, ele não será desalocado imediatamente, mas eu me pergunto o que o compilador dirá (não posso testá-lo agora) ...
Nicolas Miari
30

Em vez de usar uma estrutura , você pode criar uma classe Objective-C para gerenciar os dados.

János
fonte
quão? onde está a amostra?
Então, por que não pode estruturar para pequenos casos de uso?
Devanshu Saini
13

Isso ocorre porque o arco não pode rastrear objetos em estruturas ou uniões (já que eles são, nesse ponto, ponteiros C simples).

Mesmo que tenha marcado o arquivo / classe em questão, -fno-objc-arcvocê ainda pode passar um objeto controlado por arco para ele como parâmetro, o que provavelmente resultaria em um vazamento de memória.

voidStern
fonte
Mas então sou capaz de usar arquivos de arco e não-arco em meus projetos. Por exemplo, eu uso o sharekit como não-arc e posso usar instâncias para publicar. Os arquivos que estou usando são arquivos arc.
Zsolt
Você pode usar -fno-objc-arcpara misturar arquivos ARC e não ARC dentro de um projeto, mas se estiver usando estruturas C simples, como struct ou união em qualquer lugar, não poderá usar ARC.
voidStern
Obrigado voidStern .. "mas se você estiver usando estruturas C simples, como struct ou união em qualquer lugar, não poderá usar ARC." - Eu não acho que isso seja verdade. Estou usando o ARC para meus próprios arquivos. E não-arc para os arquivos libharu. A maneira como contornei meu problema original foi passar os valores separadamente para o arquivo C e criar a estrutura lá. Acho que a chave é o salto de arco para arco não arco e arco.
Zsolt
1
Pode ser um pouco exagerado. Em essência, você não pode colocar ponteiros para objetos em estruturas e uniões, o que confundiria o ARC. Usar uma biblioteca C simples com structs e / ou uniões deve (normalmente) ser possível.
voidStern
6

Parece que agora funciona sem erros, provavelmente após essa alteração .

ou seja, você pode colocar ponteiros normais (fortes) para objetos Objective-C em uma estrutura C. É gerenciado pelo ARC, por exemplo, não é retido quando a estrutura é destruída. Verificado com:

$ clang --version Apple LLVM version 10.0.0 (clang-1000.11.45.2)

Hiroshi Ichikawa
fonte
2
O que há de novo no LLVM - WWDC 2018
Sr. Ming