• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: -[NSGarbageCollection disableCollectorForPointer:] ?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: -[NSGarbageCollection disableCollectorForPointer:] ?


  • Subject: Re: -[NSGarbageCollection disableCollectorForPointer:] ?
  • From: "Ken Ferry" <email@hidden>
  • Date: Wed, 15 Oct 2008 16:45:11 -0700

> What I did try was
>
'NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPointerPersonality'
> which does work even though some of the pointers aren't objects and this
> doesn't seem quite correct but since I'm using GC
> NSPointerFunctionsObjectPointerPersonality seems nearly equivalent to
> NSPointerFunctionsOpaquePersonality as long as description isn't called.

I see.. I think it's a bug that
NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory
is rejected.

It's probably not very future safe to add non-objects with the object
personality.  You might prefer to use NSAllocateCollectable(NSScannedOption)
and forego the pointer array.  This allocates a chunk of memory that is:

(1) Collected by the collector when unreachable by strong reference chain
from a gc-root.
(2) Conservatively scanned.

To keep the memory alive when used as the void* contextInfo, you'd still
need to use -[NSGarbageCollector disableCollectorForPointer:].

The main gotcha is that any stores of gc objects into the buffer need to
generate write barriers, which are calls into the objective-c library that
let the collector know that the the buffer has changed and needs to be
rescanned next time a collection runs.  This should Just Work provided the
type of the buffer is __strong, but you can put doubt to rest by checking
that the compiler emitted the function calls.  In Xcode, right click and
choose "Show Assembly Code", then look for the calls.  For example, this

- (void)writeToCollectableMemory:(NSObject *)object {

    int bufferLength = 5;

    __strong void **buffer = (__strong void**)NSAllocateCollectable(sizeof(
void*)*bufferLength, NSScannedOption);

    buffer[3] = [[NSObject alloc] init];
    …

compiles to this.  objc_assign_strongCast is the function call.

"-[MyBlockOperation writeToCollectableMemory:]":

LFB672:

LM221:

LVL93:

pushl ëp

LCFI337:

movl %esp, ëp

LCFI338:

pushl %esi

LCFI339:

pushl ëx

LCFI340:

subl $16, %esp

LCFI341:

call L245

"L00000000076$pb":

L245:

popl ëx

LM222:

movl $1, 4(%esp)

movl $20, (%esp)

call _NSAllocateCollectable

movl êx, %esi

LM223:

movl L_OBJC_SELECTOR_REFERENCES_3-"L00000000076$pb"(ëx), êx

movl êx, 4(%esp)

movl L_OBJC_CLASS_REFERENCES_0-"L00000000076$pb"(ëx), êx

movl êx, (%esp)

call _objc_msgSend

movl L_OBJC_SELECTOR_REFERENCES_4-"L00000000076$pb"(ëx), íx

movl íx, 4(%esp)

movl êx, (%esp)

call _objc_msgSend

leal 12(%esi), íx

movl íx, 4(%esp)

movl êx, (%esp)

call *_objc_assign_strongCast*
…

-Ken
Cocoa Frameworks

On Wed, Oct 15, 2008 at 9:32 AM, Michael Link <email@hidden> wrote:
> That makes sense, although
> 'NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory' gives the
> error:
>
> *** -[NSPointerArray initWithOptions:] Requested configuration not
> supported.
>
> What I did try was
>
'NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPointerPersonality'
> which does work even though some of the pointers aren't objects and this
> doesn't seem quite correct but since I'm using GC
> NSPointerFunctionsObjectPointerPersonality seems nearly equivalent to
> NSPointerFunctionsOpaquePersonality as long as description isn't called.
>
> --
> Michael
>
> On Oct 15, 2008, at 1:08 AM, Ken Ferry wrote:
>
>> Hi Michael,
>>
>> NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory doesn't
>> make sense. You're meant to specify only one of the memory options and
>> only one of the personality options.
>>
>> Due to the way the bitfield work, your invocation is the same as
>> NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality.
>> This is the mode in which the pointer array is completely hands-off.
>> It acts like a C array.
>>
>> Try NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaquePersonality.
>> That sounds right to me, though I get confused with the pointer
>> functions too.
>>
>> -Ken
>>
>> On Tue, Oct 14, 2008 at 9:43 PM, Michael Link <email@hidden> wrote:
>>>
>>> I have a situation where I create an NSPointerArray on the stack by:
>>>
>>> pointers = [NSPointerArray
>>>
>>>
pointerArrayWithOptions:NSPointerFunctionsStrongMemory|NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality];
>>>
>>> I then go about adding a few objects a selector and a pointer
>>> (contextInfo
>>> that could point to anything even a non-object) to the pointer array.
>>>
>>> I then call:
>>>
>>> [[NSGarbageCollector defaultCollector]
>>> disableCollectorForPointer:pointers];
>>>
>>> The pointer array is then passed as the contextInfo for another method
>>> (which turns out to be a weak reference), but isn't garbage collected
due
>>> to
>>> the previous call. The interesting part turns out that the object at
>>> index 0
>>> (NSError* in this case) in the pointer array is garbage collected
>>> (probably
>>> because it was a variable in the function that called us). The pointer
>>> array
>>> is configured to use strong references therefore index 0 isn't set to
>>> NULL
>>> and something else is located at that memory (sometimes a different
>>> object,
>>> sometimes garbage memory).
>>>
>>> If I use:
>>>
>>> [[NSGarbageCollector defaultCollector]
>>> disableCollectorForPointer:[pointers
>>> pointerAtIndex:0]];
>>>
>>> nothing bad happens and that object isn't collected.
>>>
>>> According to the documentation for disableCollectorForPointer: shouldn't
>>> the
>>> pointer array be considered a new root object, and none of it's pointers
>>> collected? Especially since it uses strong references?
>>>
>>> --
>>> Michael
>>> _______________________________________________
>>>
>>> Cocoa-dev mailing list (email@hidden)
>>>
>>> Please do not post admin requests or moderator comments to the list.
>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>>
>>> Help/Unsubscribe/Update your Subscription:
>>>
>>> This email sent to email@hidden
>>>
>>
>>
>
>
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: -[NSGarbageCollection disableCollectorForPointer:] ?
      • From: "Ken Ferry" <email@hidden>
References: 
 >-[NSGarbageCollection disableCollectorForPointer:] ? (From: Michael Link <email@hidden>)
 >Re: -[NSGarbageCollection disableCollectorForPointer:] ? (From: "Ken Ferry" <email@hidden>)
 >Re: -[NSGarbageCollection disableCollectorForPointer:] ? (From: Michael Link <email@hidden>)

  • Prev by Date: Re: Multiple persistent store coordinators gotchas?
  • Next by Date: -[NSMutableSet addObject:] Ambiguous Docs: -isEqual: vs. ==
  • Previous by thread: Re: -[NSGarbageCollection disableCollectorForPointer:] ?
  • Next by thread: Re: -[NSGarbageCollection disableCollectorForPointer:] ?
  • Index(es):
    • Date
    • Thread