void ImageLoader::recursiveLoadLibraries(const LinkContext& context, bool preflightOnly, const RPathChain& loaderRPaths)
{
	if ( fState < dyld_image_state_dependents_mapped ) {
		// break cycles
		fState = dyld_image_state_dependents_mapped;
		
		// get list of libraries this image needs
		// 获取image需要的所有的lib的信息
		DependentLibraryInfo libraryInfos[fLibraryCount]; 
		this->doGetDependentLibraries(libraryInfos);
		
		// get list of rpaths that this image adds
		std::vector<const char*> rpathsFromThisImage;
		this->getRPaths(context, rpathsFromThisImage);
		const RPathChain thisRPaths(&loaderRPaths, &rpathsFromThisImage);
		
		// try to load each
		bool canUsePrelinkingInfo = true; 
		for(unsigned int i=0; i < fLibraryCount; ++i){
			ImageLoader* dependentLib;
			bool depLibReExported = false;
			bool depLibReRequired = false;
			bool depLibCheckSumsMatch = false;
			DependentLibraryInfo& requiredLibInfo = libraryInfos[i];
#if DYLD_SHARED_CACHE_SUPPORT
			if ( preflightOnly && context.inSharedCache(requiredLibInfo.name) ) {
				//如果存在于share_cache之中的lib不需要再lode了,因为在shared cache中的lib不会被卸载
				// <rdar://problem/5910137> dlopen_preflight() on image in shared cache leaves it loaded but not objc initialized
				// in preflight mode, don't even load dylib that are in the shared cache because they will never be unloaded
				setLibImage(i, NULL, false, false);
				continue;
			}
#endif
			try {
				dependentLib = context.loadLibrary(requiredLibInfo.name, true, this->getPath(), &thisRPaths);
				//static ImageLoader* libraryLocator(const char* libraryName, bool search, const char* origin, const ImageLoader::RPathChain* rpaths)
				if ( dependentLib == this ) {
					// 循环引用的检测
					// found circular reference, perhaps DYLD_LIBARY_PATH is causing this rdar://problem/3684168 
					dependentLib = context.loadLibrary(requiredLibInfo.name, false, NULL, NULL);
					if ( dependentLib != this )
						dyld::warn("DYLD_ setting caused circular dependency in %s\n", this->getPath());
				}
				if ( fNeverUnload )
					dependentLib->setNeverUnload();
				if ( requiredLibInfo.upward ) {
				}
				else { 
					dependentLib->fIsReferencedDownward = true;
				}
				LibraryInfo actualInfo = dependentLib->doGetLibraryInfo();
				depLibReRequired = requiredLibInfo.required;
				depLibCheckSumsMatch = ( actualInfo.checksum == requiredLibInfo.info.checksum );
				//检查checksum是否一致
				depLibReExported = requiredLibInfo.reExported;
				if ( ! depLibReExported ) {
					// for pre-10.5 binaries that did not use LC_REEXPORT_DYLIB
					// 10.5之前的程序没有LC_REXPORT_DYLIB字段,使用这种方法检测
					depLibReExported = dependentLib->isSubframeworkOf(context, this) || this->hasSubLibrary(context, dependentLib);
				}
				// check found library version is compatible
				// <rdar://problem/89200806> 0xFFFFFFFF is wildcard that matches any version
				if ( (requiredLibInfo.info.minVersion != 0xFFFFFFFF) && (actualInfo.minVersion < requiredLibInfo.info.minVersion) ) {
					// record values for possible use by CrashReporter or Finder
					// 如果依赖库的版本过低就抛出异常
					dyld::throwf("Incompatible library version: %s requires version %d.%d.%d or later, but %s provides version %d.%d.%d",
							this->getShortName(), requiredLibInfo.info.minVersion >> 16, (requiredLibInfo.info.minVersion >> 8) & 0xff, requiredLibInfo.info.minVersion & 0xff,
							dependentLib->getShortName(), actualInfo.minVersion >> 16, (actualInfo.minVersion >> 8) & 0xff, actualInfo.minVersion & 0xff);
				}
				// prebinding for this image disabled if any dependent library changed
				if ( !depLibCheckSumsMatch ) 
					canUsePrelinkingInfo = false;
				// prebinding for this image disabled unless both this and dependent are in the shared cache
				if ( !dependentLib->inSharedCache() || !this->inSharedCache() )
					//检测share_cache中是否存在需要的lib
					canUsePrelinkingInfo = false;
					
				//if ( context.verbosePrebinding ) {
				//	if ( !requiredLib.checksumMatches )
				//		fprintf(stderr, "dyld: checksum mismatch, (%u v %u) for %s referencing %s\n", 
				//			requiredLibInfo.info.checksum, actualInfo.checksum, this->getPath(), 	dependentLib->getPath());		
				//	if ( dependentLib->getSlide() != 0 )
				//		fprintf(stderr, "dyld: dependent library slid for %s referencing %s\n", this->getPath(), dependentLib->getPath());		
				//}
			}
			catch (const char* msg) {