0

I have a small agent-based modeling-framework that I'm writing as part of a project. The different agents all run in their own threads and a supervisor class controls their lifecycles. So the supervisor class can cancel these threads. I know that there is an isCancelled method on NSThread. Using that, is the following idiom acceptable:

#import <Foundation/Foundation.h>
#import "BugThread.h"
#import "Bug.h"

@implementation BugThread

- (id) initWithBug: (Bug*) aBug {

    if((self = [super init])) {
        [bug autorelease];
        bug = [aBug retain];
    }

    return self;
}

- (void) main {

    GSRegisterCurrentThread();

    while(![self isCancelled]) {
        //bug does its stuff
    }
}
jscs
  • 63,694
  • 13
  • 151
  • 195
Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • You should always retain an object **before** autoreleasing it nothing says an object can't have `autorelease` call `release` behind the scenes. – Richard J. Ross III Aug 20 '12 at 00:45
  • @RichardJ.RossIII Sorry, that was a typo! It's supposed to be `[bug autorelease];`. – Vivin Paliath Aug 20 '12 at 00:47
  • @Richard `autorelease` makes the object owned by the top autorelease pool, which won't be drained until after control leaves the current method. There is an issue here, though -- after `init` runs, the object in `bug` is not owned by this `BugThread`. Vivin, you shouldn't be sending `autorelease` to that object -- it isn't owned here. – jscs Aug 20 '12 at 00:52
  • Could you explain that last part better? What does it mean that `bug` is not owned by `BugThread`? Sorry, pretty much an Objective-C newbie here. – Vivin Paliath Aug 20 '12 at 00:54
  • This is the basics of [Cocoa memory management](http://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html): If you need an object to live, you take ownership by creating it via `alloc` or `copy`, or by retaining it. You must give up your ownership when you no longer need the object. When the object is passed in to a method, you do not own it. If you do not own an object, you must not send `release` to it (including via `autorelease`). – jscs Aug 20 '12 at 00:59
  • But `bug` is a member of the `BugThread` class so it shouldn't hurt to send autorelease to it, right? My earlier typo had me releasing `aBug`, which is the argument passed in. I can see how doing that would be wrong. – Vivin Paliath Aug 20 '12 at 01:05
  • Oh, I see. At that point (during creation of the instance), `bug` is `nil`, so sending `autorelease` actually does nothing. It's true therefore that it doesn't hurt, but it's unecessary. I guess you're copying the setter pattern, which sort of makes sense. It's just that there's nothing in that variable yet. – jscs Aug 20 '12 at 01:09

1 Answers1

3

I would say so, since this is explicitly stated in the docs:

If your thread supports cancellation, it should call this method periodically and exit if it ever returns YES.

I'd recommend that you take a look at NSOperation and NSOperationQueue, though. They're intended to allow exactly this kind of concurrency while managing the actual threads on your behalf. See "Operation Queues" in the Concurrency Programming Guide.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Does `NSOperation` and `NSOperationQueue` make multithreading easier? – Vivin Paliath Aug 20 '12 at 00:48
  • On another note, I'm doing this on GNUStep and not on OS X. It appears that NSOperation and NSOperationQueue may not be supported under GNUStep. I can't seem to find any documentation for it! – Vivin Paliath Aug 20 '12 at 00:51
  • Ah, yes. I assumed you were using Cocoa. I'm afraid I don't know much about GNUStep, but yes, `NSOperation` does make multithreading _much_ easier. – jscs Aug 20 '12 at 00:54
  • 2
    Not familiar with GNUStep however, you may want to look into GCD as well. – endy Aug 20 '12 at 00:57
  • 1
    @endy: That's a good point! [libdispatch](http://opensource.apple.com/source/libdispatch/libdispatch-228.18/) is open source, though I'm not sure how it works on other OSes. – jscs Aug 20 '12 at 01:01