GithubHelp home page GithubHelp logo

mazeroingweakref's Introduction

MAZeroingWeakRef - by Mike Ash - [email protected]

Introduction

MAZeroingWeakRef is a library for using zeroing weak references in retain/release Cocoa and Cocoa Touch code. These are references which do not keep an object alive, and which automatically become nil once the object is destroyed.

MAZeroingWeakRef does not work under Cocoa garbage collection. The built-in __weak specifier exists for that, although it is used somewhat differently.

The API is simple and mostly self-explanatory from the header file. Note that cleanup blocks are only needed for advanced uses when you need to take more action than simply zeroing the reference when the target object is destroyed. Be sure to heed the warning in the header about not doing too much work in the cleanup block.

In order to allow weak references to CoreFoundation bridged objects, a fair amount of crazy hacking of private APIs had to be done. For people who don't like that sort of thing, or who are worried about rejection when building for iOS, this crazy hacking can be reduced or disabled altogether. Look at the COREFOUNDATION_HACK_LEVEL macro in MAZeroingWeakRef.m, and the comment above it which explains what the different levels do.

A similar KVO_HACK_LEVEL macro is also available.

App Store

For iOS work, or Mac App Store work, you will probably want to set both COREFOUNDATION_HACK_LEVEL and KVO_HACK_LEVEL to 0. In this mode, MAZeroingWeakRef uses no private APIs.

Also, if you need your app to run on iOS 3.x you need to disable blocks based code setting USE_BLOCKS_BASED_LOCKING to 0.

Source Code

The MAZeroingWeakRef code is available from GitHub:

http://github.com/mikeash/MAZeroingWeakRef

MAZeroingWeakRef is made available under a BSD license.

More Information

For more information about it, this blog post gives a basic introduction to the API:

http://mikeash.com/pyblog/introducing-mazeroingweakref.html

This describes how it works in most cases:

http://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html

And this describes some of the more hairy parts:

http://mikeash.com/pyblog/friday-qa-2010-07-30-zeroing-weak-references-to-corefoundation-objects.html

Enjoy!

mazeroingweakref's People

Contributors

beelsebob avatar cysp avatar dennda avatar jdewind avatar mikeash avatar mxcl avatar psychoh13 avatar robbywalker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mazeroingweakref's Issues

Crash on iPod 1st gen with iOS 3.0

Hello.

I've been using MAZeroingWeakRef for some time without problems on devices with 4.x and above. Now I added MAZeroingWeakRef to an older project which requires all iOS compatibility support and using a weak references crashes. The crash doesn't happen immediately when creating the weak references, only when reading it back calling its target method. I've tried going back to commit 3b120d8 and see if that helped but it didn't (and don't know how far should I go without avoiding any other problems related to stuff that has been fixed).

If I modify the property getter to always return nil, the program works (with reduced functionality because parent is nil) and still crashes when deallocating the weak reference object.

To the best of my copying/pasting abilities, here's one of the limbo call stacks when it crashes:

Thread 1
 0 <????>
Thread 2
 0 mach_msg_trapA
    0x31d47144  <+0000>  mov    r12, sp
    0x31d47148  <+0004>  push   {r4, r5, r6, r8}
    0x31d4714c  <+0008>  ldm    r12, {r4, r5, r6}
    0x31d47150  <+0012>  mvn    r12, #30    ; 0x1e
    0x31d47154  <+0016>  svc    0x00000080
  * 0x31d47158  <+0020>  pop    {r4, r5, r6, r8}
    0x31d4715c  <+0024>  bx lr
 5 _pthread_body
    0x31d7058c  <+0000>  push   {r4, r7, lr}
    0x31d70590  <+0004>  add    r7, sp, #4  ; 0x4
    0x31d70594  <+0008>  mov    r4, r0
    0x31d70598  <+0012>  bl 0x31d705b8 <_pthread_set_self>
    0x31d7059c  <+0016>  ldr    r0, [r4, #60]
    0x31d705a0  <+0020>  mov    lr, pc
    0x31d705a4  <+0024>  ldr    pc, [r4, #56]
  * 0x31d705a8  <+0028>  mov    r1, r0
    0x31d705ac  <+0032>  mov    r0, r4
    0x31d705b0  <+0036>  pop    {r4, r7, lr}
    0x31d705b4  <+0040>  b  0x31d706fc <_pthread_exit>
Thread 3
 0 mach_msg_trapA
    0x31d47144  <+0000>  mov    r12, sp
    0x31d47148  <+0004>  push   {r4, r5, r6, r8}
    0x31d4714c  <+0008>  ldm    r12, {r4, r5, r6}
    0x31d47150  <+0012>  mvn    r12, #30    ; 0x1e
    0x31d47154  <+0016>  svc    0x00000080
  * 0x31d47158  <+0020>  pop    {r4, r5, r6, r8}
    0x31d4715c  <+0024>  bx lr
 7 _pthread_body
    0x31d7058c  <+0000>  push   {r4, r7, lr}
    0x31d70590  <+0004>  add    r7, sp, #4  ; 0x4
    0x31d70594  <+0008>  mov    r4, r0
    0x31d70598  <+0012>  bl 0x31d705b8 <_pthread_set_self>
    0x31d7059c  <+0016>  ldr    r0, [r4, #60]
    0x31d705a0  <+0020>  mov    lr, pc
    0x31d705a4  <+0024>  ldr    pc, [r4, #56]
  * 0x31d705a8  <+0028>  mov    r1, r0
    0x31d705ac  <+0032>  mov    r0, r4
    0x31d705b0  <+0036>  pop    {r4, r7, lr}
    0x31d705b4  <+0040>  b  0x31d706fc <_pthread_exit>
Thread 4
 0 select$DARWIN_EXTSN
    0x31d6b0cc  <+0000>  mov    r12, sp
    0x31d6b0d0  <+0004>  push   {r4, r5}
    0x31d6b0d4  <+0008>  ldr    r4, [r12]
    0x31d6b0d8  <+0012>  mov    r12, #93    ; 0x5d
    0x31d6b0dc  <+0016>  svc    0x00000080
  * 0x31d6b0e0  <+0020>  pop    {r4, r5}
    0x31d6b0e4  <+0024>  bcc    0x31d6b0fc <select$DARWIN_EXTSN+48>
    0x31d6b0e8  <+0028>  ldr    r12, [pc, #4]   ; 0x31d6b0f4 <select$DARWIN_EXTSN+40>
    0x31d6b0ec  <+0032>  ldr    r12, [pc, r12]
    0x31d6b0f0  <+0036>  b  0x31d6b0f8 <select$DARWIN_EXTSN+44>
    0x31d6b0f4  <+0040>  undefined
    0x31d6b0f8  <+0044>  bx r12
    0x31d6b0fc  <+0048>  bx lr
 3 <????>

Ignore NSCFConstantStrings

Mike,

Is there any risk of simply ignoring NSCFConstantStrings since they cannot be deallocated? it would be a matter of not doing this assert if the object is an NSCFConstantString

NSCAssert(0, @"Cannot create zeroing weak reference to object of type %@ with COREFOUNDATION_HACK_LEVEL set to %d", class, COREFOUNDATION_HACK_LEVEL);

Does not always refresh when saved

When you create a new input the UI does not refreshes when you save you need to select a new shader then go back to the one you were working on.

ZWR Runtime functions shouldn't always be used

On Snow Leopard, MAZeroingWeakRef worked with every class I tried. On Lion, it doesn't work with subclasses of NSViewController, which do not support ZWRs since NSViewController overrides retain and/or release.

I'm not sure how to check to see if a class supports ZWR, but MAZWR should fallback to the old mechanism when the runtime version of ZWR won't work.

Removing KVO observer causes crash

Since, in case of a observed KVO object, MAZeroingWeakRef just replaces the KVOClass methods (release, dealloc, classForCoder) and, according my tests, KVO resets the original object class when the last observer is removed, the replaced methods are lost.

This snippet should demonstrates the issue;

NSObject *obj = [[NSObject alloc] init];
[obj addObserver:self forKeyPath:@"description" options:NSKeyValueObservingOptionNew context:nil];
MAZeroingWeakRef *weakRef = [MAZeroingWeakRef refWithTarget:obj];
[obj removeObserver:self forKeyPath:@"description"];
[obj release];
NSLog(@"weakRef %@", weakRef.target);

Using a MAZeroingWeakRef with a ViewController causes subviews not to load from nib iOS 4.x

When using MAZeroingWeakRef with a UIViewController as the target the VC's view's subviews do not get loaded from the nib. This only happens if the MAZeroingWeakRef is created before the VC's viewDidLoad: method is called (for example in the initWithNibName:bundle: method) and you are running iOS 4.x.

I have created a simple example project that will demonstrate this:
https://github.com/rcancro/MAZWRTestApp

For a work around I've found that you can either force viewDidLoad: to be called before creating the MAZeroingWeakRef (by doing something like self.view.hidden = NO;) or create an init function for the ViewController that calls through to initWithNibName:bundle: passing in the nib name.

There are more details on the project's github page.

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.