Giter Site home page Giter Site logo

Comments (13)

GunGraveKoga avatar GunGraveKoga commented on May 12, 2024

Only one work around i can use^

void * t = &(*self);

[self.MyStorage storeBlock: ^void(){
    Worker* tmp = (Worker *)t;

    of_log(@"I am block from %p", tmp);
    of_log(@"I am retained %d times", [tmp retainCount]); //1 retain count
}];

from objfw.

fjolnir avatar fjolnir commented on May 12, 2024

Did you try __unsafe_unretained id welf = self; ?

from objfw.

Midar avatar Midar commented on May 12, 2024

Capturing self is intended behaviour of blocks - Foundation + Apple runtime have the exact same behaviour.

__unsafe_unretained won't help here at all, as this is non-ARC code and __unsafe_unretained is just defined to nothing. A workaround here would be to pass it using void*, however, what you're doing here doesn't make much sense in the first place: Why would you have blocks that reference self stored in self? You did not tell us what exactly you are trying to achieve, but I'm quite certain whatever it is, there is a better way to do it that does not require any hacks like passing it using void*. I would recommend you join #objfw on irc.freenode.net and tell us what exactly you are trying to do, the bug tracker is not the right venue for that.

As an aside, I'm very interested in how you got ObjFW to work with Clang. Last time I checked, Clang had problems with ObjC code on Windows, as that would result in it emitting weak symbols, which are not available on Windows.

from objfw.

fjolnir avatar fjolnir commented on May 12, 2024

Ah, no ARC. __block id capturedSelf is what he wants then.

of course it's important to note that if the code is ever migrated to arc, __block will no longer break the retain cycle.

from objfw.

GunGraveKoga avatar GunGraveKoga commented on May 12, 2024

About "Clang had problems with ObjC code on Windows, as that would result in it emitting weak symbols, which are not available on Windows."
I do not know what kind of problem You're talking about is actually. If it is some thing like this http://clang.llvm.org/docs/UsersManual.html#gcc-extensions-not-implemented-yet or this https://trac.mpich.org/projects/mpich/ticket/1815, I can't find "weak" in sources of ObjFW, but I has some output from llvm-nm
$ llvm-nm /C/Proj/objfw-master/src/*.dll |grep weak
00000000 A .weak.__Jv_RegisterClasses._hmod_libgcc
00000000 A .weak.__OBJC_CLASS_OFConstantString.default
00000000 A .weak.___deregister_frame_info._hmod_libgcc
00000000 A .weak.___register_frame_info._hmod_libgcc
00000000 A .weak._class_registerAlias_np.default
I am not so good know about compilers specific features
If You interest, I am use this tools:
http://sourceforge.net/projects/clangonwin/files/MingwBuild/3.6/llvm-win64-r222867-x86_64-w64-mingw32.zip/download Clang
http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-posix/dwarf/i686-4.9.2-release-posix-dwarf-rt_v3-rev1.7z/download GCC and MinGW build tools & libs

Configuring of building ObjFW Sources:
./configure --build=x86_64-w64-mingw32 --host=i686-w64-mingw32 --prefix=/C/mingw-w64/objfw OBJC=clang OBJCFLAGS=--target=i686-w64-mingw32 -isystem /C/mingw-w64/i686-4.9.2-posix-dwarf-rt_v3-rev1/mingw32/i686-w64-mingw32/include -isystem /C/mingw-w64/i686-4.9.2-posix-dwarf-rt_v3-rev1/mingw32/lib/gcc/i686-w64-mingw32/4.9.2/include -isystem /C/mingw-w64/i686-4.9.2-posix-dwarf-rt_v3-rev1/mingw32/i686-w64-mingw32/include/c++

Also I use Assembler like this AS = clang --target=i686-w64-mingw32 ASFLAGS = -no-integrated-as
And add -Xclang flag in configure.ac for Clang specific compilation flags:
OBJCFLAGS="$OBJCFLAGS -Xclang -fobjc-runtime=objfw"
OBJCFLAGS="$OBJCFLAGS -Xclang -fblocks"
OBJCFLAGS="$OBJCFLAGS -Xclang -fno-constant-cfstrings"

Post-build test, integrated in ObjFW sources finished successfully for all steps
All integrated applications (OFHash OFZip OFHttp) works fine
All features from ObjC, that I tested, works fine:
@autoreleasepool
@Property
@synthesize
@synchronized
@dynamic
Blocks
Calng literals for String, Array, Number, Dictionary etc
I have only one problem - crash while using OFProcess for Windows program

from objfw.

Midar avatar Midar commented on May 12, 2024

@fjolnir __block only adds a level of indirection and does not do what you want it to do here.

@GunGraveKoga ObjFW itself does not use weak references, however, clang's CodeGen for ObjC generated weak references last time I tried. I'll have to give it another try in Windows, maybe that bug has been fixed by now. For reference, from where did you acquire MinGW and from where Clang?

from objfw.

GunGraveKoga avatar GunGraveKoga commented on May 12, 2024

@Midar http://sourceforge.net/projects/clangonwin/files/MingwBuild/3.6/llvm-win64-r222867-x86_64-w64-mingw32.zip/download that link for Clang
and
http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-posix/dwarf/i686-4.9.2-release-posix-dwarf-rt_v3-rev1.7z/download for GCC tools and MinGW libtools and also http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download for Unix-like environment if You talking about this
I do not build those tools manually

from objfw.

Midar avatar Midar commented on May 12, 2024

Ok, I'll give this a try. I just tried it again with Clang form MSys2, which still shows the behaviour I described above.

In any case, I'm closing this bug, as everything is working as intended.

from objfw.

fjolnir avatar fjolnir commented on May 12, 2024

@Midar It doesn't? I'm fairly sure a __block captured object is not supposed to get retained. (It would be problematic if it did)
Could you explain what you mean?

#import <ObjFW/ObjFW.h>

@interface Canary : OFObject
@end

@implementation Canary
- (void)dealloc
{
    printf("dealloc\n");
    [super dealloc];
}
@end

int main()
{
    __block id foo = [Canary new];
    id (^blk)() = [^{ return foo; } copy];
    [foo release];
    printf("returning from main\n");
}

from objfw.

Midar avatar Midar commented on May 12, 2024

@fjolnir I guess I should have said "not only". It does, as a side effect, not retain it, that's true, but it has some other side effects as well. Essentially, the type of the variable is not object pointer anymore, but byref. A byref adds an extra level of indirection, so each access has to do one more dereference to get back to the object pointer. It also means copying the block needs to:

a.) Copy the byref itself to the heap
b.) Copy the variable to the heap
c.) Adjust the byref so that from now on all accesses go through the one copied to the heap, and not to the one on the stack.

All that in addition to copying the block itself, obviously. As you can see, this adds quite a lot of overhead that is totally useless here, as the object pointer itself is never modified. Just copying the object pointer is sufficient here, even if you modify the object pointed to. So instead of changing the type to byref to avoid the retain that's done on objects, it's better to create a non-object pointer. The value of that pointer is then just copied instead of creating all the byref overhead.

See also OFBlock.m for more details.

from objfw.

fjolnir avatar fjolnir commented on May 12, 2024

Sure, I know that. I've also implemented a block runtime :)
But it's the only way to break a cycle like this apart from architecture change

from objfw.

Midar avatar Midar commented on May 12, 2024

No, it's not the only way - see the above. Just using a void* gives you the same result without creating unnecessary byrefs ;).

I was not aware there is any other blocks runtime than Apple's, Psy|'s PoC with quite a few bugs (I think it even predated the release of Apple's), GNUstep's, compiler-rt's and - obviously - ObjFW's. Which one is it? :)

from objfw.

fjolnir avatar fjolnir commented on May 12, 2024

Well, I guess I wrote the compiler bits rather than the runtime functions, but same knowledge is required :)
https://github.com/fjolnir/Tranquil/blob/master/Source/Tranquil/CodeGen/TQNodeBlock.mm

TQ sits on apple's runtime, but adds boxing on top of it:
https://github.com/fjolnir/Tranquil/blob/master/Source/Tranquil/Runtime/TQBlockClosure.m

from objfw.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.