Se você não pode obter um objeto com objectAtIndex: de um NSSet, como você recupera objetos?
objective-c
cocoa
cocoa-touch
object
nsset
ninja ninja
fonte
fonte
[[nsSetObjects allObjects] objectAtIndex: anyInteger]
Respostas:
Existem vários casos de uso para um conjunto. Você pode enumerar por meio de (por exemplo, com
enumerateObjectsUsingBlock
ou NSFastEnumeration), chamarcontainsObject
para testar a associação, usaranyObject
para obter um membro (não aleatório) ou convertê-lo em uma matriz (sem nenhuma ordem específica) comallObjects
.Um conjunto é apropriado quando você não deseja duplicatas, não se preocupa com a ordem e deseja um teste de adesão rápido.
fonte
member:
mensagem ao conjunto . Se retornarnil
, o conjunto não contém um objeto igual ao que você passou; se retornar um ponteiro de objeto, o ponteiro que ele retorna é para o objeto já no conjunto. Os objetos do conjunto devem implementarhash
eisEqual:
para que isso seja útil.hash
precisa ser implementado; seria muito mais rápido se você fizesse isso.hash
no protocolo NSObject: “Se dois objetos são iguais (conforme determinado peloisEqual:
método), eles devem ter o mesmo valor de hash.” Atualmente, as implementações do NSObjecthash
eisEqual:
usam a identidade do objeto (endereço). Se você substituirisEqual:
, estará configurando a possibilidade de objetos que não são idênticos, mas são iguais - os quais, se você também não substituirhash
, ainda terão hashes diferentes. Isso viola o requisito de que objetos iguais tenham hashes iguais.member:
, o contêiner só procurará naquele bucket (é por isso que os conjuntos são muito mais rápidos do que os arrays no teste de associação e os dicionários são muito mais rápidos do que os arrays paralelos na pesquisa de valor-chave). Se o objeto procurado tiver o hash errado, o contêiner procurará no balde errado e não encontrará uma correspondência.-[NSObject hash]
era 0. Isso explica muita coisa. = SNSSet não tem um método objectAtIndex:
Tente chamar allObjects que retorna um NSArray de todos os objetos.
fonte
é possível usar filterSetUsingPredicate se você tiver algum tipo de identificador exclusivo para selecionar o objeto que você precisa.
Primeiro crie o predicado (supondo que seu id único no objeto é chamado de "identificador" e é um NSString):
Em seguida, escolha o objeto usando o predicado:
fonte
NSArray *myArray = [myNSSet allObjects];
substitua NSUInteger pelo índice do objeto desejado.
fonte
Para Swift3 e iOS10:
fonte
O NSSet usa o método isEqual: (que os objetos colocados naquele conjunto devem substituir, além disso, o método hash) para determinar se um objeto está dentro dele.
Portanto, por exemplo, se você tiver um modelo de dados que define sua exclusividade por um valor de id (digamos que a propriedade seja:
então você implementaria isEqual: as
e você pode implementar hash:
Então, você pode obter um objeto com esse ID (bem como verificar se ele está no NSSet) com:
Mas sim, a única maneira de obter algo de um NSSet é considerando o que define sua singularidade em primeiro lugar.
Não testei o que é mais rápido, mas evito usar enumeração porque isso pode ser linear, enquanto usar o método member: seria muito mais rápido. Essa é uma das razões para preferir o uso de NSSet em vez de NSArray.
fonte
fonte
Na maioria das vezes, você não se preocupa em obter um objeto específico de um conjunto. Você se preocupa em testar para ver se um conjunto contém um objeto. É para isso que servem os conjuntos. Quando você deseja ver se um objeto está em uma coleção, os conjuntos são muito mais rápidos do que os arrays.
Se você não se preocupam com que objeto que você começa, o uso
-anyObject
que apenas lhe dá um objeto a partir do conjunto, como colocar a mão em um saco e pegar alguma coisa.Se você se preocupa com o objeto que obtém, use o
-member
que devolve o objeto, ou nil se não estiver no conjunto. Você precisa já ter o objeto antes de chamá-lo.Aqui estão alguns códigos que você pode executar no Xcode para entender mais
fonte