Is it possible to get a list of pointer to a pointers to an objective c object.
something like
id **pointers(id object, int *out_count)
Pretty crazy, huh? =)
Unfortunately, no. If such a thing were generally possible, then writing a precise garbage collector would be rather simple:
int count;
pointers(obj, &count);
if (count == 0) {
free(obj);
}
Since the objective-c garbage collector has to chase pointers from roots, control the allocator, and scan the stack conservatively to achieve something like this, I think it's reasonable to assume that you'd need to do the same.
It might be possible to leverage the garbage collector's implementation of this, though, if running in GC mode. Not a good idea, not simple, and won't work on iOS, but maybe possible. libauto is open source after all.
Related
I read this question in stackoverflow.
The excerpt answer provided by bbum is below:
The problem isn't the assignment, it is much more likely that you
declared your instance variable to be BOOL *initialBroadcast;.
There is no reason to declare the instance variable to be a pointer
(at least not unless you really do need a C array of BOOLs).. Remove
the * from the declaration.
1.Is there anything wrong in using a pointer variable even when I do not have to maintain an array of BOOLs?
2.I think even if avoiding them a good practice, it is not specific to objective-C and applies to all programming languages which has pointers.
Please answer my questions.
1.Is there anything wrong in using a pointer variable even when I do not have to maintain an array of BOOLs?
It's not illegal to do so, but it is bad practice. Using a pointer variable requires that you manage that memory (allocate and free it), and there are whole classes of bugs that can occur as a result. If you forget to allocate the memory, or accidentally modify the pointer, your program could crash, or you could overwrite some other part of memory. If you forget to free the memory, you have a memory leak. None of these things can ever happen if you're just using a plain BOOL. In addition, you get no benefit from using a pointer here; you do a bunch of extra work, and get nothing in return.
2.I think even if avoiding them a good practice, it is not specific to objective-C and applies to all programming languages which has
pointers.
I don't know about "all programming languages which [have] pointers", but I would certainly say in any C-based language (C, C++, Objective-C), it's bad practice to use pointers to intrinsic types when a plain variable of that type will do. If you can avoid doing memory management, do so.
On a side note, it is good practice to listen to everything bbum says. Seriously.
I'm studying ARC. And now about zeroing weak pointer.
OK I understood all the features. The semantic of weak reference is just same with weak reference of GC system, but you know, Objective-C doesn't use GC (except special case) so I can't understand how this works.
I'm a little complicated guy, so I need to know underlying implementation principal to accept the feature to use. But the problem is it's very hard to find document which describes the principal of zeroing-weak pointer :(
IMO, the only way to make this work is tracking and keeping all pointers referencing itself at runtime, and setting them all nil when its referencing count becomes 0. But this looks too heavy and stupid. I believe a lot better solution used in actual ARC implementation.
Can you help me to find the documentation? Or direct description would be more great!
It's explained here:
http://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html
Spoiler:
It works pretty much how you'd think. Every class maintains a set of addresses of weak pointers that are pointing to it, and when its dealloc is called it sets them all to zero.
It may seem dumb, but it's fast because there's no "tracking" involved, ARC just inserts the code to add a pointer to that set every time the object is assigned to a new weak reference.
It's actually much more efficient than the trickery involved in Garbage collection, which basically involves wading through the heap on a background thread looking for pointers and keeping stock of what they're pointing to.
Implemented by a global hash table in runtime.
Apple source: https://opensource.apple.com/source/objc4/objc4-647/runtime/objc-weak.mm
I would like to know witch is the best practice to test if void pointer is actually an objective C object pointer (NSObject*)...
- (id)initWithExecPath:(NSString*)executePath withArgs:(NSArray*)args identifier:(NSString*)identifierString contextInfo:(void*)contextInfo {
// I would like to check here if contextInfo is an NSObject
}
Thanks...
Check out this post from the CocoaWithLove site:
In this post, I look at an approach for testing if an arbitrary
pointer is a pointer to a valid Objective-C object. The result from
the test is not absolutely accurate and can interfere with gdb
debugging if the pointer isn't a valid memory location, so this is not
something you'd want to do often (and certainly not in production
code). But it can be a handy debugging tool for when you're staring
blindly at memory you didn't allocate.
The answer is that no you can't provide a general test for "is an Objective-C object". Any such test would have to examine the internal structure of an object and is therefore fragile by definition. There is also the possibility of being handed a random piece of memory that looks like an Objective-C object but isn't. e.g. a recently deallocated object.
There is no reliable way to determine this. Also, any API that takes a context pointer shouldn't care what it is or what it points to, it shouldn't do anything with it other than pass it back to the caller as context.
Perhaps you are asking the wrong question; what exactly do you want to do once you know it is an NSObject?
I've never worked with a language that didn't provide for some form of memory management, and thus managed to get by without ever really groking pointers.
I can dabble in C I guess, as a result of coding in Objective-C for a little while.
Hmmm, maybe it's the single linked list.
Try it: create, populate, reverse, release a single linked list
struct node {
int data;
struct node *next;
};
I wouldn't call this "canonical", but I'm recreating [arrayOfStrings sortUsingSelector:#selector(compare:)]; using char * arrays and pure C code. It's sloppy and frustrating, but great practice and I'm loving it.
http://github.com/jkubicek/Objective-Sort/blob/master/Objective-Sort.m
I've started a small github project to collect objective-c katas: https://github.com/twobitlabs/xcode-katas
I have this in my #interface
struct track currentTrack;
struct track previousTrack;
int anInt;
Since these are not objects, I do not have to have them like int* anInt right?
And if setting non-object values like ints, boolean, etc, I do not have to release the old value right (assuming non-GC environment)?
The struct contains objects:
typedef struct track {
NSString* theId;
NSString* title;
} *track;
Am I doing that correctly?
Lastly, I access the struct like this:
[currentTrack.title ...];
currentTrack.theId = #"asdf"; //LINE 1
I'm also manually managing the memory (from a setter) for the struct like this:
[currentTrack.title autorelease];
currentTrack.title = [newTitle retain];
If I'm understanding the garbage collection correctly, I should be able to ditch that and just set it like LINE 1 (above)?
Also with garbage collection, I don't need a dealloc method right?
If I use garbage collection does this mean it only runs on OS 10.5+? And any other thing I should know before I switch to garbage collected code?
Sorry there are so many questions. Very new to objective-c and desktop programming.
Thanks
I have this in my #interface
struct track currentTrack;
struct track previousTrack;
int anInt;
Since these are not objects, I do not have to have them like int* anInt right?
That would declare a pointer to an int stored somewhere else.
And if setting non-object values like ints, boolean, etc, I do not have to release the old value right (assuming non-GC environment)?
release is a message. You can only send a message to a Cocoa (or, in some cases, Core Foundation) object.
The struct contains objects:
typedef struct track {
NSString* theId;
NSString* title;
More precisely, it contains pointers to objects.
You can't ever have an object stored directly in a variable; you can only allocate it dynamically by sending an alloc message to a class, and receive the pointer to the allocated instance. Similarly, you can only send a message to a pointer to an object; you cannot and should not dereference a pointer to an object.
For these reasons, we almost always elide the “a pointer to”. We speak of the pointers as if they are the objects, but, in precise truth, they are not.
} *track;
That's correct if you want to declare the track type as being a pointer to a struct track. Generally, this will confuse people.
Lastly, I access the struct like this:
[currentTrack.title ...];
currentTrack.theId = #"asdf"; //LINE 1
So the previous line is line 0? ;)
I'm also manually managing the memory (from a setter) for the struct like this:
[currentTrack.title autorelease];
currentTrack.title = [newTitle retain];
If I'm understanding the garbage collection correctly, I should be able to ditch that and just set it like LINE 1 (above)?
If you're using garbage collection, then the autorelease and retain messages will do nothing, so yes, the plain assignment and the assignment with (ineffectual) release and retain messages are equivalent.
I do question why you're putting this information in a structure and not a model object, though.
Also with garbage collection, I don't need a dealloc method right? If I use garbage collection does this mean it only runs on OS 10.5+? And any other thing I should know before I switch to garbage collected code?
Yes: Read the Garbage Collection Programming Guide. It tells you everything you need to know, including the answers to the previous two questions.
As for pointers, you may want to read my pointers tutorial. The title says C, but everything in C is also true in Objective-C.
Although you seem to understand this stuff all right in general, I'd strongly recommand against storing objects in a struct. Getting proper memory management for that will be very troublesome — because even though the struct itself doesn't require memory management, the objects still do, and unless the struct is only ever accessed through a function API (essentially making it s poor man's object), you're going to have a tough time ensuring that happens. Like Peter said, that makes sense to be a model object.
Correct, correct, no, yes, correct, yes, and Apple's Garbage Collection Programming Guide is a good read.