[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSRunLoop with ARC
From: |
David Chisnall |
Subject: |
Re: NSRunLoop with ARC |
Date: |
Wed, 16 Oct 2013 19:37:14 +0100 |
Hi,
Banlu pointed me at this question from someone (you?) on Stack Overflow today.
The short version: it's a bug, it's fixed in svn, and it's in -base, so update
-base and this code should work again.
The long version:
The cause of the bug was the NSFileHandle method that is supposed to return a
singleton instance for standard input. There was a memory management bug in
this code. The singleton was assigned to a global, autoreleased, and returned.
It was not retained before assigning it to the global (which didn't look like
it was required, because it was just created with +alloc, but that code didn't
know that the there was another autorelease in the calling method).
With non-ARC code, this rarely matters. If you retain the result, it will
exist you release it (and, as long as at least one object always holds a
reference to it, the singleton instance stays valid). Similarly, in simple
test cases like yours, the top-level autorelease pool holds the reference to it
until program access.
This shows up with ARC, because ARC introduced a mechanism for popping the top
object from the autorelease pool. This meant that, as soon as you'd called the
waitForDataInBackgroundAndNotify method on the file handle, it was deallocated,
even though it is a singleton that should not be deallocated just because you
stop holding a reference to it.
I have now fixed the NSFileHandle bug (and added a non-ARC test case to the
test suite that triggers it).
David
On 16 Oct 2013, at 04:50, "Hoon H." <drawtree@gmail.com> wrote:
> Hello.
> I am Hoon and trying GNUstep for server-side web development.
> I think if it supports collection classes and std/socket I/O, then it's
> enough to use for me.
>
> Anyway, at first try (command-line echo app), I found some strange behavior.
> `NSRunLoop`
> didn't work well with ARC.
>
> When I issued `-[NSRunLoop run]` method with installing std-in I/O observer,
> I expected it to
> run infinitely. And on OSX, GNUstep, it worked as I expected. But only
> *without* ARC.
> When I turned on ARC on GNUstep, the run-loop quits immediately.
>
> ARC itself works well because I could observe object deallocation.
> So I have no idea why GNUstep behaves differently only under ARC enabled.
>
> Should I treat this as a bug? Or am I missing something?
>
> Here's my test code, compile command, and environment.
>
>
>
>
> #import <Foundation/Foundation.h>
>
> @interface AAA : NSObject
> - (void)test1:(id)s;
> @end
> @implementation AAA
> - (void)test1:(id)s
> {
> NSLog(@"%@", s);
> }
> - (void)dealloc
> {
> NSLog(@"DEALLOCED!!");
> }
> @end
>
> int main(int argc, const char * argv[])
> {
> @autoreleasepool
> {
> AAA* aaa = [[AAA alloc] init];
> [[NSNotificationCenter defaultCenter] addObserver:aaa
> selector:@selector(test1:) name:NSFileHandleDataAvailableNotification
> object:nil];
>
> [[NSFileHandle fileHandleWithStandardInput]
> waitForDataInBackgroundAndNotify];
> [[NSRunLoop currentRunLoop] run];
> }
> return 0;
> }
>
>
>
>
>
> Compile command:
>
>
>
>
> clang -v
> EE_GNUSTEP_OPTS="-MMD -MP -DGNUSTEP -DGNUSTEP_BASE_LIBRARY=1
> -DGNU_RUNTIME=1 -DGNUSTEP_BASE_LIBRARY=1 -fno-strict-aliasing -fexceptions
> -fobjc-exceptions -D_NATIVE_OBJC_EXCEPTIONS -D_NONFRAGILE_ABI -pthread -fPIC
> -Wall -DGSWARN -DGSDIAGNOSE -Wno-import -g -fgnu-runtime
> -fconstant-string-class=NSConstantString"
> EE_BUILD_OPTS="-I/usr/local/include -L/usr/local/lib -lc -lobjc
> -lgnustep-base -fblocks -fobjc-arc -fobjc-abi-version=3"
> alias OBJCC="clang $EE_GNUSTEP_OPTS $EE_BUILD_OPTS"
> OBJCC *.m
>
> ./a.out
>
>
>
>
> Environment:
>
> - FreeBSD 9.2-RELEASE
> - GNUstep(make:2.6.5, base:1.24.5)
> - libobjc2(1.7)
>
> My installation script.
>
> echo "Writtne for csh."
> echo "Switch to Clang. Ensure you're using 3.3 or above."
> setenv CC clang
> setenv CXX clang++
> setenv CPP clang-cpp
>
> echo "Prerequisites."
> pkg_add -r portmaster
> cd /usr/ports
> portmaster --no-confirm -G security/gnutls textproc/libxslt devel/icu
> devel/libdispatch devel/libffi
>
> echo "GNUstep(make:2.6.5, base:1.24.5) + libobjc2(1.7) on FreeBSD 9.2."
> echo "The versions are chosen for production. Do not upgrade without
> test."
> cd ~/
> mkdir t1
> cd t1
> pkg_add -r subversion gmake
> svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/releases/1.7
> libobjc2-1.7 &
> svn co http://svn.gna.org/svn/gnustep/tools/make/tags/make-2_6_5
> make-2_6_5 &
> svn co http://svn.gna.org/svn/gnustep/libs/base/tags/base-1_24_5
> base-1_24_5 &
> wait
>
> cd make-2_6_5
> ./configure --enable-objc-nonfragile-abi
> gmake install
> cd ..
>
> cd libobjc2-1.7
> gmake install
> cd ..
>
> cd make-2_6_5
> ./configure --enable-objc-nonfragile-abi
> gmake install
> cd ..
>
> echo "Now we need to set some path to GNUstep to use gnustep-make."
> source /usr/GNUstep/System/Library/Makefiles/GNUstep.csh
>
> cd base-1_24_5
> ./configure --enable-fake-main --disable-unicodeconstants --disable-tls
> gmake install
> cd ..
>
>
>
> _______________________________________________
> Discuss-gnustep mailing list
> Discuss-gnustep@gnu.org
> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
-- Sent from my brain