Comments (13)
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.
Did you try __unsafe_unretained id welf = self;
?
from objfw.
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.
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.
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.
@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.
@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.
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.
@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.
@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.
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.
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.
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)
- Support for structs in -[NSInvocation invoke] on x86_64/SysV HOT 1
- Create an objfw.library for AmigaOS/MorphOS HOT 1
- [utils/ofhttp] Average the speed and ETA HOT 1
- [utils/ofhttp] Multi-stream downloads HOT 1
- Add documentation for runtime functions HOT 1
- [OFDNSResolver] Support for URI records HOT 1
- [OFProcess] Support for retrieving the exit code HOT 2
- [runtime] Add objc_setAssociatedObject() HOT 1
- Write assembly for dispatch on MIPS64/N32 HOT 1
- Write assembly for forwardingTargetForSelector: on MIPS64/N32 ABI HOT 1
- [OFStream,OFRunLoop] Notification of OFStream readiness to read, EOF HOT 3
- [OFStream] atEndOfStream - read()/recv() returning 0 shouldn't mean stream is permanently atEnd HOT 2
- [OFProcess] posix_spawnp failure sets an unspecified PID, which `- close` attempts to kill HOT 2
- AUR package HOT 8
- Support OOB data for TCP HOT 1
- Review all APIs before 1.0 release HOT 1
- Automated test for OFProcess HOT 1
- [question] Metal HOT 1
- ObjFW and llvm-mingw HOT 7
- amiga-gcc, NDK3.2 and ObjFW HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from objfw.