Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Paying Down Debt

Samuel E. Giddins
September 04, 2015
60

Paying Down Debt

Closing talk given at iOS Dev Camp DC 2015.

Samuel E. Giddins

September 04, 2015
Tweet

Transcript

  1. git log | tail -n 30 commit ed68b4631621be8a09786eeef9653a4fde2028e8 Author: Eloy

    Duran <[email protected]> Date: Sat Aug 13 23:00:15 2011 +0200 More work on README. commit 3e80b4cad120e35d23d9a44cdf7eb52ec70beac3 Author: Eloy Duran <[email protected]> Date: Sat Aug 13 17:40:11 2011 +0200 Rename a bit commit 5889b9bbdf22e30782821e507c3ec0d83d4ec602 Author: Eloy Duran <[email protected]> Date: Sat Aug 13 17:39:00 2011 +0200 Add an example PodSpec.rb file commit 8aa61846580eb4ade7a92d3031d3ac4813bb94ef Author: Eloy Duran <[email protected]> Date: Sat Aug 13 02:14:56 2011 +0200 Add notes about kit commit fd2bc0a7cc4c49ddc37edb2a16398f8cfb06132e Author: Eloy Duran <[email protected]> Date: Sat Aug 13 01:58:11 2011 +0200 Initial import
  2. cloc $(git ls-files) 319 text files. 318 unique files. 50

    files ignored. http://cloc.sourceforge.net v 1.62 T=0.41 s (656.7 files/s, 95326.7 lines/s) -------------------------------------------------------------------------------- Language files blank comment code -------------------------------------------------------------------------------- Ruby 265 6664 3330 28660 YAML 3 72 101 211 Bourne Again Shell 1 2 1 5 -------------------------------------------------------------------------------- SUM: 269 6738 3432 28876 --------------------------------------------------------------------------------
  3. commit 9d3890e96f0ebbd358f5f2d5ee619dea7f8e7310 Author: Samuel E. Giddins <[email protected]> Date: Mon Aug

    24 11:50:51 2015 -0700 Avoid deadlocks in standalone object initialization diff --git a/Realm/RLMAccessor.mm b/Realm/RLMAccessor.mm index a9525fe..537caee 100644 --- a/Realm/RLMAccessor.mm +++ b/Realm/RLMAccessor.mm @@ -597,6 +597,12 @@ void RLMReplaceSharedSchemaMethod(Class accessorClass, RLMObjectSchema *schema) class_replaceMethod(metaClass, @selector(sharedSchema), imp, "@@:"); } +void RLMReplaceSharedSchemaMethodWithBlock(Class accessorClass, RLMObjectSchema *(^method)(Class)) { + Class metaClass = objc_getMetaClass(class_getName(accessorClass)); + IMP imp = imp_implementationWithBlock(method); + class_replaceMethod(metaClass, @selector(sharedSchema), imp, "@@:"); +} + static Class RLMCreateAccessorClass(Class objectClass, RLMObjectSchema *schema, NSString *accessorClassPrefix, diff --git a/Realm/RLMObjectBase.h b/Realm/RLMObjectBase.h index 8184c2c..925e8e5 100644 --- a/Realm/RLMObjectBase.h +++ b/Realm/RLMObjectBase.h @@ -33,7 +33,7 @@ RLM_ASSUME_NONNULL_BEGIN + (NSString *)className; -/// Returns whether the class is included in the default set of classes persisted in a Realm. +// Returns whether the class is included in the default set of classes persisted in a Realm. + (BOOL)shouldIncludeInDefaultSchema; @end diff --git a/Realm/RLMSchema.mm b/Realm/RLMSchema.mm index d4c5f8f..2d9f514 100644 --- a/Realm/RLMSchema.mm +++ b/Realm/RLMSchema.mm @@ -41,8 +41,8 @@ const uint64_t RLMNotVersioned = realm::ObjectStore::NotVersioned; @end static RLMSchema *s_sharedSchema; -static RLMSchema *s_partialSharedSchema; -static NSMutableDictionary *s_localNameToClass; +static RLMSchema *s_partialSharedSchema = [[RLMSchema alloc] init]; +static NSMutableDictionary *s_localNameToClass = [[NSMutableDictionary alloc] init]; @implementation RLMSchema @@ -85,23 +85,13 @@ static NSMutableDictionary *s_localNameToClass; } } -+ (void)initialize { - static bool initialized; - if (initialized) { - return; - } - initialized = true; - - s_localNameToClass = [NSMutableDictionary dictionary]; - s_partialSharedSchema = [[RLMSchema alloc] init]; -} - + (instancetype)partialSharedSchema { return s_partialSharedSchema; } + (void)registerClasses:(Class *)classes count:(NSUInteger)count { @synchronized(s_localNameToClass) { + auto threadID = pthread_mach_thread_np(pthread_self()); // first create class to name mapping so we can do array validation // when creating object schema for (NSUInteger i = 0; i < count; i++) { @@ -134,8 +124,17 @@ static NSMutableDictionary *s_localNameToClass; s_localNameToClass[className] = cls; RLMReplaceClassNameMethod(cls, className); - // override sharedSchema classs method to return nil to avoid topo-sort issues - RLMReplaceSharedSchemaMethod(cls, nil); + // override sharedSchema classs method to return nil to avoid topo-sort issues when on this thread + // (i.e. while during schema initialization), but wait on other threads until schema initialization is done, + // then return the just-initialized schema + RLMReplaceSharedSchemaMethodWithBlock(cls, ^RLMObjectSchema *(Class cls) { + if (threadID == pthread_mach_thread_np(pthread_self())) { + return nil; + } + @synchronized(s_localNameToClass) { + return [cls sharedSchema]; + } + }); }
  4. Coding best practice: if you see code you don’t immediately

    understand “why” you should delete it and see what happens. — @Dirk_Gently
  5. Object-oriented programming is an exceptionally bad idea which could only

    have originated in California. — Edsger Dijkstra
  6. We have a zero-tolerance policy for performance regressions. If a

    patch lands that regresses performance according to our benchmarks, then the person responsible must either back the patch out of the tree or drop everything immediately and fix the regression.
  7. Common excuses people give when they regress performance are, "But

    the new way is cleaner!" or "The new way is more correct." We don't care. No performance regressions are allowed, regardless of the reason. There is no justification for regressing performance. None.
  8. Be assured that it gives much more pain to the

    mind to be in debt, than to do without any article whatever which we may seem to want. — Thomas Jefferson