Here I have a bunch of dispatch_queue_t, and I want to organize them with a NSArray. But as far as I know, there's no such API to do so. So how can i achieve that?
NSArray is not mutable. You must use NSMutableArray, that is subclass of NSArray, to add objects.
And, from iOS 6.0 SDK and the Mac OS X 10.8 SDK, Dispatch Queue is declared as Objective-C types. Thus you can use Dispatch Queue object as Objective-C object.
#import Foundation;
int main()
{
NSMutableArray *array = [[NSMutableArray alloc] init];
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
NSLog(#" q=%#", q);
[array addObject:q];
NSLog(#"array[0]=%#", array[0]);
return 0;
}
Result:
q=<OS_dispatch_queue_root: com.apple.root.default-qos[0x7fff79749b40]>
array[0]=<OS_dispatch_queue_root: com.apple.root.default-qos[0x7fff79749b40]>
Related
We're porting over some C++ .h to Objective C .h files.
Here is a sample of the C++ code we're trying to port over for our class.
std::vector< std::vector< int > > D2DMap;
std::vector< std::vector< int > > D3DMap;
We have yet to be successful in declaring an equivalent in Obj-C.
NSMutableArray *D2DMap = [[NSMutableArray alloc] init];
NSMutableArray *inner = [[NSMutableArray alloc] init];
[inner addObject:[NSNumber numberWithInt:someInt]];
[D2DMap addObject:inner];
But we know this is wrong because it is not dynamic at run time.
You could use Objective-C++.
If you don't want to use Objective-C++, you're sort of out of luck. There is no non-dynamically-typed array in the Cocoa library. You could hack together a solution involving malloc and other generally disgusting things, but I'd recommend against it.
This question already has answers here:
What is the meaning of id?
(5 answers)
Closed 9 years ago.
To begin, i'm not very comfortable with Objective c, i'm trying to convert a C++ class into an Objective C and i'm having trouble with the implementation on my class this is what i got for c++
UniqueWord::UniqueWord(const string word, const int line)
{
wordCatalog=word;
count = 0;
addLine(line);
}
//Deconstructor.
UniqueWord::~UniqueWord(void)
{
}
and this is what i got for Objective C
#implementation UniqueWord
-(id)initWithString:(NSString*)str andline:(NSInteger)line{
_wordCatalog=str;
count=0;
addline(line);
return ?//return what? it states (Control reaches end of non-void function)
}
I'm really new to classes in objective c, so i'm also asking for a dumbed down answer to,What in the world is an "id" and how do you use it?
Objective C constructors a little bit different. You should create something like following:
-(instancetype)initWithString:(NSString*)str andline:(NSInteger)line{
self = [super init];
if(self == nil) return nil;
_wordCatalog=str;
count=0;
addline(line);
return self;
}
id is a generic class in Objective-C. This is somewhat similar to void* of C++, but with a lot more support from the execution environment so as to not require much typecasting.
There is no parallel concept in C++: an untyped object reference lets you use objects dynamically, with the specifics of the call checked at runtime, rather than at compile time.
Also note that Objective-C uses initializers instead of constructors. The two serve similar purposes, but are not the same: constructors can operate either together with operator new or separately from it, while initializers can operate only with the method that does allocation. Additionally, an initializer can return a different object in place of the one provided by alloc; constructors cannot do that.
An id is a point to any object in Objective-C. An init method returns an allocated and instantiated object. I would refer you to the Apple docs regarding initializers at https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/Initialization/Initialization.html
In using what the article above says you'll want to write something like.
- (instancetype)initWithString:(NSString *)str andLine:(NSInteger)line {
self = [super init];
if (self) {
_wordCatalog = str;
}
return self;
The typical form (which you should use) for init methods is like this:
- (id)init
{
if ( (self = [super init] ) )
{
[other code you want in the constructor]
}
return self;
}
So for the method you have, it should look something like this:
-(id)initWithString:(NSString*)str andline:(NSInteger)line{
if ( (self = [super init]) )
{
_wordCatalog=str;
count=0;
addline(line);
}
return self;
}
That is, unless the super class has an initWithString:andline: constructor, in which case you would use
if ( (self = [super initWithString:string andline:line) )
as the if statement.
I'm implementing some fast sort algorithms, and to get best performances, I'd like to use a C++ binding in Objective-C. But I want my algorithms to work with user custom objects and with something similar to a NSComparator ; which type may I use in C++ to use these objects ? May I template a class ?
Please let me know about your best solution to bind custom objects in C++ and to use a NSComparator in C++ ?
Best regards,
Hervé HL.
With the help of #Dave, I finally found the solution to extract pointers from NSArray, no matter the contained type, do some complex operations, and then reassemble the pointers, using void * type.
Just rename your .m file to .mm to enable Objective-C++ features.
void *array[[self count]]; //create an empty void* array
for (uint i = 0; i < [self count]; i++)
{
int address = (int)[self objectAtIndex:i];
array[i] = (void *)address; //insert NSObjects pointers into void* array
}
To get back the NSObjects from void* array, just proceed like this:
NSMutableArray *doneAr = [[NSMutableArray alloc] init]; //create a NSMutableArray
for (uint i = 0; i < [self count]; i++)
{
void *tmp = (void **)done + i; //extract the pointer in the void* array
NSString *strTmp = (NSString *)(*((Class *)tmp)); //convert it back to origin type (here NSString *)
[doneAr addObject:strTmp]; //add it back to the previously created NSMutableArray
}
Hope this answer could be helpful for future issues. If you wish to use NSComparator like me in your C++ implementation, just rename your .m file into .mm file so as you can use Objective-C++ features ; then import and use what you need (NSComparator for example).
I have declared an NSMutableArray *categories in my view controller .h file, and declared a property for it.
In the parser:foundCharacters: method of the NSXMLParser delegate in my .m file, I have this code:
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
if (elementFound)
{
element = string;
[self.categories addObject:element];
}
}
But when I hover over the [self.categories addObject:element] line after stepping into it in debug mode, XCode tells me the size is 0x0, 0 objects. There are 3 elements in my XML file so 3 items should be in the array.
I'm missing something really obvious and I can't figure out what.
The "0x0" part is a memory address. Specifically, "nil", which means your mutable array doesn't exist at the time this is being called. Try creating it in your -init method:
categories = [[NSMutableArray alloc] init];
Don't forget to release it in your -dealloc.
Initialize an empty array using
categories = [NSMutableArray array];
The array class method are autoreleased so no need to release.
In my application, i have a mix of C++ and Objective C++ code, at one place, i need to insert pointer of c++ class object to NSMutableArray , but i am getting NSINvalidArgument exception,
Can anyone guide me, how can i insert void pointer to NSMuatableArray
This is what i have tried ,
pArray = [[NSMutableArray alloc]initWithCapacity:myList.size()];
Node *node = myList.getHead();
int idx =0;
void *ptr = nil;
while ( node ) {
[pCTArray insertObject:(NSObject *)node atIndex:idx];
node = node->getNext();
idx++;
}
Is there any otherway to insert it into the MutableArray,
the possible workaround i made is : having store index link this
[myArray insertObject:[NSNumber numberWithInt:idx] atIndex:idx];
and this array i would be using in all NSTable/NSOutliveVIew delegate method , i need to pick the index and get the element from the linklist, but worried because of performance, as too many function call would be needed,
Is this any bug in Cocoa or i am making anything wrong ?
NSArrays expect to hold objective-C objects conforming to the NSObject protocol. If you wish to wrap a pointer, use NSValue:
[myArray insertObject:[NSValue valueWithPointer:node] atIndex:idx];
You are manually responsible for all memory management of that pointer, as objective-C can't reference count it in the usual way.
NSMurableArray only accepts Objective-C objects (hence the argument type of addObject: being id).
Are you on the Mac or iOS? If you're on the Mac, You might want to look at NSPointerArray.
You might also be able to be CFMutableArray with custom callback functions, but I haven't tried this myself.
A third option is NSPointerArray.